From 0803674f4940c328a1ae3e409d3ed73d389e9d90 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 19:47:31 +0000 Subject: [PATCH] deploy: f5478a8af2b3c9a75092ed36ddb9fd768b6556ad --- 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 ++-- 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 | 8 ++++---- algorithms/index.html | 6 +++--- algorithms/rb-trees/applications/index.html | 4 ++-- algorithms/rb-trees/rules/index.html | 4 ++-- algorithms/recursion/karel-1/index.html | 4 ++-- .../recursion/pyramid-slide-down/index.html | 6 +++--- algorithms/tags/applications/index.html | 4 ++-- algorithms/tags/backtracking/index.html | 4 ++-- algorithms/tags/balanced-trees/index.html | 4 ++-- algorithms/tags/bfs/index.html | 4 ++-- algorithms/tags/bottom-up-dp/index.html | 4 ++-- algorithms/tags/c/index.html | 4 ++-- algorithms/tags/cpp/index.html | 4 ++-- algorithms/tags/csharp/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/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.2f775329.js => 1535ede8.504968c0.js} | 2 +- ...c7293.8e9a4314.js => 595c7293.ac56f8be.js} | 2 +- ...5d476.73f34dd7.js => 5fe5d476.de49fc9d.js} | 2 +- ...2c0bc.7402024f.js => 7052c0bc.4005bc03.js} | 2 +- ...ef108.166aea3d.js => 794ef108.17b0c630.js} | 2 +- ...1e0d8.7240ea58.js => 84d1e0d8.a087077b.js} | 2 +- ...4fd5d.143c547f.js => aa24fd5d.e4465696.js} | 2 +- ...88602.2548704d.js => b1288602.70376235.js} | 2 +- ...e838c.ac17e06f.js => d05e838c.f0798c93.js} | 2 +- .../js/{main.a809bb25.js => main.9ec99e33.js} | 4 ++-- ...CENSE.txt => main.9ec99e33.js.LICENSE.txt} | 0 ...n.306284ce.js => runtime~main.a44959d8.js} | 2 +- blog/2023/08/02/copr/index.html | 4 ++-- 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/index.html | 4 ++-- blog/leetcode/sort-diagonally/index.html | 4 ++-- 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/copr/index.html | 4 ++-- blog/tags/cpp/index.html | 4 ++-- blog/tags/index.html | 4 ++-- blog/tags/iterators/index.html | 4 ++-- blog/tags/leetcode/index.html | 4 ++-- blog/tags/red-hat/index.html | 4 ++-- blog/tags/rust/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 1933 -> 1942 bytes .../graphs/iterative-and-iterators.tar.gz | Bin 1956 -> 1954 bytes files/algorithms/recursion/karel-1.tar.bz2 | Bin 5877 -> 5874 bytes files/algorithms/recursion/karel-1.tar.gz | Bin 6583 -> 6580 bytes .../recursion/pyramid-slide-down.tar.bz2 | Bin 1547 -> 1545 bytes .../recursion/pyramid-slide-down.tar.gz | Bin 1422 -> 1419 bytes .../algorithms/time-complexity/extend.tar.bz2 | Bin 4083 -> 4070 bytes .../algorithms/time-complexity/extend.tar.gz | Bin 3912 -> 3911 bytes files/c/bonuses/03.tar.bz2 | Bin 2651 -> 2633 bytes files/c/bonuses/03.tar.gz | Bin 2336 -> 2335 bytes files/c/bonuses/04.tar.bz2 | Bin 2534 -> 2526 bytes files/c/bonuses/04.tar.gz | Bin 2500 -> 2499 bytes files/c/bonuses/05-06.tar.bz2 | Bin 3637 -> 3623 bytes files/c/bonuses/05-06.tar.gz | Bin 3485 -> 3485 bytes files/c/bonuses/08.tar.bz2 | Bin 73476 -> 73485 bytes files/c/bonuses/08.tar.gz | Bin 103304 -> 103298 bytes files/c/bonuses/10.tar.bz2 | Bin 234845 -> 234834 bytes files/c/bonuses/10.tar.gz | Bin 230109 -> 230105 bytes index.html | 4 ++-- search/index.html | 4 ++-- talks/index.html | 4 ++-- 116 files changed, 194 insertions(+), 194 deletions(-) rename assets/js/{1535ede8.2f775329.js => 1535ede8.504968c0.js} (99%) rename assets/js/{595c7293.8e9a4314.js => 595c7293.ac56f8be.js} (99%) rename assets/js/{5fe5d476.73f34dd7.js => 5fe5d476.de49fc9d.js} (99%) rename assets/js/{7052c0bc.7402024f.js => 7052c0bc.4005bc03.js} (95%) rename assets/js/{794ef108.166aea3d.js => 794ef108.17b0c630.js} (95%) rename assets/js/{84d1e0d8.7240ea58.js => 84d1e0d8.a087077b.js} (97%) rename assets/js/{aa24fd5d.143c547f.js => aa24fd5d.e4465696.js} (58%) rename assets/js/{b1288602.2548704d.js => b1288602.70376235.js} (98%) rename assets/js/{d05e838c.ac17e06f.js => d05e838c.f0798c93.js} (99%) rename assets/js/{main.a809bb25.js => main.9ec99e33.js} (99%) rename assets/js/{main.a809bb25.js.LICENSE.txt => main.9ec99e33.js.LICENSE.txt} (100%) rename assets/js/{runtime~main.306284ce.js => runtime~main.a44959d8.js} (94%) diff --git a/404.html b/404.html index a536c3f..50ff2fe 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 ba4751f..f725507 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 b22d093..b58c90c 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 871b66d..79dd516 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 8825a08..1dab830 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 e38c8d3..5e7c976 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/recursion/index.html b/algorithms/category/recursion/index.html index 0685682..af5f8dc 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 4e7a532..e3b3f45 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 7289178..90e24cb 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 239d57a..f0b983c 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 d0a4ae0..685d308 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 7d5f661..c323e6e 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 da3c26e..d244299 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

@@ -87,9 +87,9 @@ even though it's rather comparable with the first progressive sequence with regards to the insertion phase.

If we were to compare the always conflicting one with the first one, we can see that insertion took over 7Ă— longer and lookups almost 9Ă— longer.

-

You can have a look at the code here.

+

You can have a look at the code here.

Comparing with the tree​

-
danger

Source code can be found here.

Viewer discretion advised.

+
danger

Source code can be found here.

Viewer discretion advised.

Python doesn't have a tree structure for sets/maps implemented, therefore for a comparison we will run a similar benchmark in C++. By running the same sequences on both hash table and tree (RB-tree) we will obtain the following diff --git a/algorithms/index.html b/algorithms/index.html index 4e76449..8fe61e9 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/rb-trees/applications/index.html b/algorithms/rb-trees/applications/index.html index c0d702d..40ca350 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 80f8747..aa6bc4f 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-1/index.html b/algorithms/recursion/karel-1/index.html index b1027fe..a0d1b6c 100644 --- a/algorithms/recursion/karel-1/index.html +++ b/algorithms/recursion/karel-1/index.html @@ -16,8 +16,8 @@ - - + +

Recursion and backtracking with Robot Karel

\ No newline at end of file diff --git a/algorithms/tags/applications/index.html b/algorithms/tags/applications/index.html index 8b336f3..8e1cff0 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/backtracking/index.html b/algorithms/tags/backtracking/index.html index 1282d61..1f8ebd8 100644 --- a/algorithms/tags/backtracking/index.html +++ b/algorithms/tags/backtracking/index.html @@ -14,8 +14,8 @@ - - + +

One doc 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 95de2c5..a156a6c 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/bfs/index.html b/algorithms/tags/bfs/index.html index 1eb865c..6905eff 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 e216ee1..ad22c09 100644 --- a/algorithms/tags/bottom-up-dp/index.html +++ b/algorithms/tags/bottom-up-dp/index.html @@ -14,8 +14,8 @@ - - + +

One doc tagged with "bottom-up-dp"

View All Tags

Introduction to dynamic programming

Solving a problem in different ways. diff --git a/algorithms/tags/c/index.html b/algorithms/tags/c/index.html index bf42e15..dd6294e 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 e4c2abe..9101e23 100644 --- a/algorithms/tags/cpp/index.html +++ b/algorithms/tags/cpp/index.html @@ -14,8 +14,8 @@ - - + +

3 docs tagged with "cpp"

View All Tags

Breaking Hash Table

How to get the linear time complexity in a hash table. diff --git a/algorithms/tags/csharp/index.html b/algorithms/tags/csharp/index.html index d22449b..bbe3a68 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/dynamic-array/index.html b/algorithms/tags/dynamic-array/index.html index a9cb7e1..05e4c65 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 d57a5a4..ef6d059 100644 --- a/algorithms/tags/dynamic-programming/index.html +++ b/algorithms/tags/dynamic-programming/index.html @@ -14,8 +14,8 @@ - - + +

One doc tagged with "dynamic-programming"

View All Tags

Introduction to dynamic programming

Solving a problem in different ways. diff --git a/algorithms/tags/exponential/index.html b/algorithms/tags/exponential/index.html index 10d92c3..0ecf636 100644 --- a/algorithms/tags/exponential/index.html +++ b/algorithms/tags/exponential/index.html @@ -14,8 +14,8 @@ - - + +

One doc 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 8a487e8..c4b5da4 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 ccb1797..9c0fc98 100644 --- a/algorithms/tags/greedy/index.html +++ b/algorithms/tags/greedy/index.html @@ -14,8 +14,8 @@ - - + +

One doc tagged with "greedy"

View All Tags

Introduction to dynamic programming

Solving a problem in different ways. diff --git a/algorithms/tags/hash-tables/index.html b/algorithms/tags/hash-tables/index.html index 09789e5..2d9e711 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 0c92216..63da3d7 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 364f32b..beba350 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 74e66df..cf1299a 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 dd3005a..4117a6a 100644 --- a/algorithms/tags/java/index.html +++ b/algorithms/tags/java/index.html @@ -14,8 +14,8 @@ - - + +

One doc tagged with "java"

View All Tags

Introduction to dynamic programming

Solving a problem in different ways. diff --git a/algorithms/tags/karel/index.html b/algorithms/tags/karel/index.html index c0fea66..af3b229 100644 --- a/algorithms/tags/karel/index.html +++ b/algorithms/tags/karel/index.html @@ -14,8 +14,8 @@ - - + +

One doc 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 cb401c9..184ce23 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 cbe3591..f5de073 100644 --- a/algorithms/tags/python/index.html +++ b/algorithms/tags/python/index.html @@ -14,8 +14,8 @@ - - + +

6 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 1216514..20762b0 100644 --- a/algorithms/tags/recursion/index.html +++ b/algorithms/tags/recursion/index.html @@ -14,8 +14,8 @@ - - + +

3 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 23e95cd..f77bbab 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/sorting/index.html b/algorithms/tags/sorting/index.html index 922e62a..c19f205 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 16194c1..e4364a6 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 cd1d0b8..d65db07 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 07e2038..8a0852f 100644 --- a/algorithms/tags/top-down-dp/index.html +++ b/algorithms/tags/top-down-dp/index.html @@ -14,8 +14,8 @@ - - + +

One doc 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 e222f92..55f5977 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.2f775329.js b/assets/js/1535ede8.504968c0.js similarity index 99% rename from assets/js/1535ede8.2f775329.js rename to assets/js/1535ede8.504968c0.js index 0442ac3..177f53d 100644 --- a/assets/js/1535ede8.2f775329.js +++ b/assets/js/1535ede8.504968c0.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:1701199517,formattedLastUpdatedAt:"Nov 28, 2023",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:1701200735,formattedLastUpdatedAt:"Nov 28, 2023",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/595c7293.8e9a4314.js b/assets/js/595c7293.ac56f8be.js similarity index 99% rename from assets/js/595c7293.8e9a4314.js rename to assets/js/595c7293.ac56f8be.js index baabd65..25f8872 100644 --- a/assets/js/595c7293.8e9a4314.js +++ b/assets/js/595c7293.ac56f8be.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:1701199517,formattedLastUpdatedAt:"Nov 28, 2023",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:1701200735,formattedLastUpdatedAt:"Nov 28, 2023",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/5fe5d476.73f34dd7.js b/assets/js/5fe5d476.de49fc9d.js similarity index 99% rename from assets/js/5fe5d476.73f34dd7.js rename to assets/js/5fe5d476.de49fc9d.js index efef806..5eb5566 100644 --- a/assets/js/5fe5d476.73f34dd7.js +++ b/assets/js/5fe5d476.de49fc9d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[2619],{14457:(s,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>t,default:()=>o,frontMatter:()=>l,metadata:()=>r,toc:()=>m});var a=n(85893),i=n(11151);const l={id:"pyramid-slide-down",title:"Introduction to dynamic programming",description:"Solving a problem in different ways.\n",tags:["java","recursion","exponential","greedy","dynamic-programming","top-down-dp","bottom-up-dp"],last_updated:{date:new Date("2023-08-17T00:00:00.000Z")}},t=void 0,r={id:"recursion/pyramid-slide-down",title:"Introduction to dynamic programming",description:"Solving a problem in different ways.\n",source:"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down.md",sourceDirName:"04-recursion",slug:"/recursion/pyramid-slide-down",permalink:"/algorithms/recursion/pyramid-slide-down",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/04-recursion/2023-08-17-pyramid-slide-down.md",tags:[{label:"java",permalink:"/algorithms/tags/java"},{label:"recursion",permalink:"/algorithms/tags/recursion"},{label:"exponential",permalink:"/algorithms/tags/exponential"},{label:"greedy",permalink:"/algorithms/tags/greedy"},{label:"dynamic-programming",permalink:"/algorithms/tags/dynamic-programming"},{label:"top-down-dp",permalink:"/algorithms/tags/top-down-dp"},{label:"bottom-up-dp",permalink:"/algorithms/tags/bottom-up-dp"}],version:"current",lastUpdatedAt:1701199517,formattedLastUpdatedAt:"Nov 28, 2023",frontMatter:{id:"pyramid-slide-down",title:"Introduction to dynamic programming",description:"Solving a problem in different ways.\n",tags:["java","recursion","exponential","greedy","dynamic-programming","top-down-dp","bottom-up-dp"],last_updated:{date:"2023-08-17T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Recursion and backtracking with Robot Karel",permalink:"/algorithms/recursion/karel-1"},next:{title:"Red-Black Trees",permalink:"/algorithms/category/red-black-trees"}},c={},m=[{value:"Problem",id:"problem",level:2},{value:"Solving the problem",id:"solving-the-problem",level:2},{value:"Na\xefve solution",id:"na\xefve-solution",level:2},{value:"Time complexity",id:"time-complexity",level:3},{value:"Greedy solution",id:"greedy-solution",level:2},{value:"Time complexity",id:"time-complexity-1",level:3},{value:"Running the tests",id:"running-the-tests",level:3},{value:"Top-down DP",id:"top-down-dp",level:2},{value:"Time complexity",id:"time-complexity-2",level:3},{value:"Memory complexity",id:"memory-complexity",level:3},{value:"Bottom-up DP",id:"bottom-up-dp",level:2},{value:"Time complexity",id:"time-complexity-3",level:3},{value:"Memory complexity",id:"memory-complexity-1",level:3},{value:"Summary",id:"summary",level:2}];function h(s){const e={a:"a",admonition:"admonition",annotation:"annotation",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",li:"li",math:"math",mdxAdmonitionTitle:"mdxAdmonitionTitle",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",mspace:"mspace",mstyle:"mstyle",msub:"msub",msup:"msup",mtable:"mtable",mtd:"mtd",mtext:"mtext",mtr:"mtr",munderover:"munderover",ol:"ol",p:"p",pre:"pre",section:"section",semantics:"semantics",span:"span",strong:"strong",sup:"sup",...(0,i.a)(),...s.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.p,{children:"In this post we will try to solve one problem in different ways."}),"\n",(0,a.jsx)(e.h2,{id:"problem",children:"Problem"}),"\n",(0,a.jsxs)(e.p,{children:["The problem we are going to solve is one of ",(0,a.jsx)(e.em,{children:"CodeWars"})," katas and is called\n",(0,a.jsx)(e.a,{href:"https://www.codewars.com/kata/551f23362ff852e2ab000037",children:"Pyramid Slide Down"}),"."]}),"\n",(0,a.jsxs)(e.p,{children:["We are given a 2D array of integers and we are to find the ",(0,a.jsx)(e.em,{children:"slide down"}),".\n",(0,a.jsx)(e.em,{children:"Slide down"})," is a maximum sum of consecutive numbers from the top to the bottom."]}),"\n",(0,a.jsx)(e.p,{children:"Let's have a look at few examples. Consider the following pyramid:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:" 3\n 7 4\n 2 4 6\n8 5 9 3\n"})}),"\n",(0,a.jsx)(e.p,{children:"This pyramid has following slide down:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:" *3\n *7 4\n 2 *4 6\n8 5 *9 3\n"})}),"\n",(0,a.jsxs)(e.p,{children:["And its value is ",(0,a.jsx)(e.code,{children:"23"}),"."]}),"\n",(0,a.jsxs)(e.p,{children:["We can also have a look at a ",(0,a.jsx)(e.em,{children:"bigger"})," example:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:" 75\n 95 64\n 17 47 82\n 18 35 87 10\n 20 4 82 47 65\n 19 1 23 3 34\n 88 2 77 73 7 63 67\n 99 65 4 28 6 16 70 92\n 41 41 26 56 83 40 80 70 33\n 41 48 72 33 47 32 37 16 94 29\n 53 71 44 65 25 43 91 52 97 51 14\n 70 11 33 28 77 73 17 78 39 68 17 57\n 91 71 52 38 17 14 91 43 58 50 27 29 48\n 63 66 4 68 89 53 67 30 73 16 69 87 40 31\n 4 62 98 27 23 9 70 98 73 93 38 53 60 4 23\n"})}),"\n",(0,a.jsxs)(e.p,{children:["Slide down in this case is equal to ",(0,a.jsx)(e.code,{children:"1074"}),"."]}),"\n",(0,a.jsx)(e.h2,{id:"solving-the-problem",children:"Solving the problem"}),"\n",(0,a.jsx)(e.admonition,{type:"caution",children:(0,a.jsxs)(e.p,{children:["I will describe the following ways you can approach this problem and implement\nthem in ",(0,a.jsx)(e.em,{children:"Java"}),(0,a.jsx)(e.sup,{children:(0,a.jsx)(e.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]})}),"\n",(0,a.jsxs)(e.p,{children:["For all of the following solutions I will be using basic ",(0,a.jsx)(e.code,{children:"main"})," function that\nwill output ",(0,a.jsx)(e.code,{children:"true"}),"/",(0,a.jsx)(e.code,{children:"false"})," based on the expected output of our algorithm. Any\nother differences will lie only in the solutions of the problem. You can see the\n",(0,a.jsx)(e.code,{children:"main"})," here:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:'public static void main(String[] args) {\n System.out.print("Test #1: ");\n System.out.println(longestSlideDown(new int[][] {\n { 3 },\n { 7, 4 },\n { 2, 4, 6 },\n { 8, 5, 9, 3 }\n }) == 23 ? "passed" : "failed");\n\n System.out.print("Test #2: ");\n System.out.println(longestSlideDown(new int[][] {\n { 75 },\n { 95, 64 },\n { 17, 47, 82 },\n { 18, 35, 87, 10 },\n { 20, 4, 82, 47, 65 },\n { 19, 1, 23, 75, 3, 34 },\n { 88, 2, 77, 73, 7, 63, 67 },\n { 99, 65, 4, 28, 6, 16, 70, 92 },\n { 41, 41, 26, 56, 83, 40, 80, 70, 33 },\n { 41, 48, 72, 33, 47, 32, 37, 16, 94, 29 },\n { 53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14 },\n { 70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57 },\n { 91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48 },\n { 63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31 },\n { 4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23 },\n }) == 1074 ? "passed" : "failed");\n}\n'})}),"\n",(0,a.jsx)(e.h2,{id:"na\xefve-solution",children:"Na\xefve solution"}),"\n",(0,a.jsx)(e.p,{children:"Our na\xefve solution consists of trying out all the possible slides and finding\nthe one with maximum sum."}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid, int row, int col) {\n if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {\n // BASE: We have gotten out of bounds, there's no reasonable value to\n // return, so we just return the \u2039MIN_VALUE\u203a to ensure that it cannot\n // be maximum.\n return Integer.MIN_VALUE;\n }\n\n if (row == pyramid.length - 1) {\n // BASE: Bottom of the pyramid, we just return the value, there's\n // nowhere to slide anymore.\n return pyramid[row][col];\n }\n\n // Otherwise we account for the current position and return maximum of the\n // available \u201cslides\u201d.\n return pyramid[row][col] + Math.max(\n longestSlideDown(pyramid, row + 1, col),\n longestSlideDown(pyramid, row + 1, col + 1));\n}\n\npublic static int longestSlideDown(int[][] pyramid) {\n // We start the slide in the top cell of the pyramid.\n return longestSlideDown(pyramid, 0, 0);\n}\n"})}),"\n",(0,a.jsx)(e.p,{children:"As you can see, we have 2 overloads:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"int longestSlideDown(int[][] pyramid);\nint longestSlideDown(int[][] pyramid, int row, int col);\n"})}),"\n",(0,a.jsxs)(e.p,{children:["First one is used as a ",(0,a.jsx)(e.em,{children:"public interface"})," to the solution, you just pass in the\npyramid itself. Second one is the recursive \u201calgorithm\u201d that finds the slide\ndown."]}),"\n",(0,a.jsxs)(e.p,{children:["It is a relatively simple solution\u2026 There's nothing to do at the bottom of the\npyramid, so we just return the value in the ",(0,a.jsx)(e.em,{children:"cell"}),". Otherwise we add it and try\nto slide down the available cells below the current row."]}),"\n",(0,a.jsx)(e.h3,{id:"time-complexity",children:"Time complexity"}),"\n",(0,a.jsx)(e.p,{children:"If you get the source code and run it yourself, it runs rather fine\u2026 I hope you\nare wondering about the time complexity of the proposed solution and, since it\nreally is a na\xefve solution, the time complexity is pretty bad. Let's find the\nworst case scenario."}),"\n",(0,a.jsx)(e.p,{children:"Let's start with the first overload:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid) {\n return longestSlideDown(pyramid, 0, 0);\n}\n"})}),"\n",(0,a.jsxs)(e.p,{children:["There's not much to do here, so we can safely say that the time complexity of\nthis function is bounded by ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T(n)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]}),", where ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"T"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6833em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"})]})})]})," is our second overload. This\ndoesn't tell us anything, so let's move on to the second overload where we are\ngoing to define the ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T(n)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})," function."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid, int row, int col) {\n if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {\n // BASE: We have gotten out of bounds, there's no reasonable value to\n // return, so we just return the \u2039MIN_VALUE\u203a to ensure that it cannot\n // be maximum.\n return Integer.MIN_VALUE;\n }\n\n if (row == pyramid.length - 1) {\n // BASE: Bottom of the pyramid, we just return the value, there's\n // nowhere to slide anymore.\n return pyramid[row][col];\n }\n\n // Otherwise we account for the current position and return maximum of the\n // available \u201cslides\u201d.\n return pyramid[row][col] + Math.max(\n longestSlideDown(pyramid, row + 1, col),\n longestSlideDown(pyramid, row + 1, col + 1));\n}\n"})}),"\n",(0,a.jsxs)(e.p,{children:["Fun fact is that the whole \u201calgorithm\u201d consists of just 2 ",(0,a.jsx)(e.code,{children:"return"})," statements\nand nothing else. Let's dissect them!"]}),"\n",(0,a.jsxs)(e.p,{children:["First ",(0,a.jsx)(e.code,{children:"return"})," statement is the base case, so it has a constant time complexity."]}),"\n",(0,a.jsxs)(e.p,{children:["Second one a bit tricky. We add two numbers together, which we'll consider as\nconstant, but for the right part of the expression we take maximum from the left\nand right paths. OK\u2026 So what happens? We evaluate the ",(0,a.jsx)(e.code,{children:"longestSlideDown"})," while\nchoosing the under and right both. They are separate computations though, so we\nare branching from each call of ",(0,a.jsx)(e.code,{children:"longestSlideDown"}),", unless it's a base case."]}),"\n",(0,a.jsx)(e.p,{children:"What does that mean for us then? We basically get"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mo,{fence:"true",children:"{"}),(0,a.jsxs)(e.mtable,{rowspacing:"0.36em",columnalign:"left left",columnspacing:"1em",children:[(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"false",children:(0,a.jsx)(e.mn,{children:"1"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"false",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mtext,{children:",\xa0if\xa0"}),(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"})]})})})]}),(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"false",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mn,{children:"1"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mn,{children:"1"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"false",children:(0,a.jsx)(e.mtext,{children:",\xa0otherwise"})})})]})]})]})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T(y) =\n\\begin{cases}\n1 & \\text{, if } y = rows \\\\\n1 + 2 \\cdot T(y + 1) & \\text{, otherwise}\n\\end{cases}"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mclose",children:")"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"3em",verticalAlign:"-1.25em"}}),(0,a.jsxs)(e.span,{className:"minner",children:[(0,a.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:(0,a.jsx)(e.span,{className:"delimsizing size4",children:"{"})}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsxs)(e.span,{className:"mtable",children:[(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.69em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.69em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.008em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord",children:"1"})})]}),(0,a.jsxs)(e.span,{style:{top:"-2.25em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.008em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord",children:"1"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord",children:"1"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.19em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"arraycolsep",style:{width:"1em"}}),(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.69em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.69em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.008em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord text",children:(0,a.jsx)(e.span,{className:"mord",children:",\xa0if\xa0"})}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})]})]}),(0,a.jsxs)(e.span,{style:{top:"-2.25em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.008em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord text",children:(0,a.jsx)(e.span,{className:"mord",children:",\xa0otherwise"})})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.19em"},children:(0,a.jsx)(e.span,{})})})]})})]})}),(0,a.jsx)(e.span,{className:"mclose nulldelimiter"})]})]})]})]})}),"\n",(0,a.jsx)(e.p,{children:"That looks rather easy to compute, isn't it? If you sum it up, you'll get:"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mo,{children:"\u2208"}),(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsxs)(e.msup,{children:[(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"})]})]}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T(rows) \\in \\mathcal{O}(2^{rows})"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"\u2208"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsx)(e.span,{className:"vlist-t",children:(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.7144em"},children:(0,a.jsxs)(e.span,{style:{top:"-3.113em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsxs)(e.span,{className:"mord mtight",children:[(0,a.jsx)(e.span,{className:"mord mathnormal mtight",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal mtight",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal mtight",children:"s"})]})})]})})})})})]}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,a.jsx)(e.p,{children:"If you wonder why, I'll try to describe it intuitively:"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:["In each call to ",(0,a.jsx)(e.code,{children:"longestSlideDown"})," we do some work in constant time,\nregardless of being in the base case. Those are the ",(0,a.jsx)(e.code,{children:"1"}),"s in both cases."]}),"\n",(0,a.jsxs)(e.li,{children:["If we are not in the base case, we move one row down ",(0,a.jsx)(e.strong,{children:"twice"}),". That's how we\nobtained ",(0,a.jsx)(e.code,{children:"2 *"})," and ",(0,a.jsx)(e.code,{children:"y + 1"})," in the ",(0,a.jsx)(e.em,{children:"otherwise"})," case."]}),"\n",(0,a.jsxs)(e.li,{children:["We move row-by-row, so we move down ",(0,a.jsx)(e.code,{children:"y"}),"-times and each call splits to two\nsubtrees."]}),"\n",(0,a.jsxs)(e.li,{children:["Overall, if we were to represent the calls as a tree, we would get a full\nbinary tree of height ",(0,a.jsx)(e.code,{children:"y"}),", in each node we do some work in constant time,\ntherefore we can just sum the ones."]}),"\n"]}),"\n",(0,a.jsx)(e.admonition,{type:"warning",children:(0,a.jsx)(e.p,{children:"It would've been more complicated to get an exact result. In the equation above\nwe are assuming that the width of the pyramid is bound by the height."})}),"\n",(0,a.jsxs)(e.p,{children:["Hopefully we can agree that this is not the best we can do. ","\ud83d\ude09"]}),"\n",(0,a.jsx)(e.h2,{id:"greedy-solution",children:"Greedy solution"}),"\n",(0,a.jsxs)(e.p,{children:["We will try to optimize it a bit. Let's start with a relatively simple ",(0,a.jsx)(e.em,{children:"greedy"}),"\napproach."]}),"\n",(0,a.jsx)(e.admonition,{title:"Greedy algorithms",type:"info",children:(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.em,{children:"Greedy algorithms"})," can be described as algorithms that decide the action on the\noptimal option at the moment."]})}),"\n",(0,a.jsx)(e.p,{children:"We can try to adjust the na\xefve solution. The most problematic part are the\nrecursive calls. Let's apply the greedy approach there:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid, int row, int col) {\n if (row == pyramid.length - 1) {\n // BASE: We're at the bottom\n return pyramid[row][col];\n }\n\n if (col + 1 >= pyramid[row + 1].length\n || pyramid[row + 1][col] > pyramid[row + 1][col + 1]) {\n // If we cannot go right or it's not feasible, we continue to the left.\n return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col);\n }\n\n // Otherwise we just move to the right.\n return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col + 1);\n}\n"})}),"\n",(0,a.jsxs)(e.p,{children:["OK, if we cannot go right ",(0,a.jsx)(e.strong,{children:"or"})," the right path adds smaller value to the sum,\nwe simply go left."]}),"\n",(0,a.jsx)(e.h3,{id:"time-complexity-1",children:"Time complexity"}),"\n",(0,a.jsxs)(e.p,{children:["We have switched from ",(0,a.jsx)(e.em,{children:"adding the maximum"})," to ",(0,a.jsx)(e.em,{children:"following the \u201cbigger\u201d path"}),", so\nwe improved the time complexity tremendously. We just go down the pyramid all\nthe way to the bottom. Therefore we are getting:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(rows)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})}),"\n",(0,a.jsx)(e.p,{children:"We have managed to convert our exponential solution into a linear one."}),"\n",(0,a.jsx)(e.h3,{id:"running-the-tests",children:"Running the tests"}),"\n",(0,a.jsx)(e.p,{children:"However, if we run the tests, we notice that the second test failed:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:"Test #1: passed\nTest #2: failed\n"})}),"\n",(0,a.jsxs)(e.p,{children:["What's going on? Well, we have improved the time complexity, but greedy\nalgorithms are not the ideal solution to ",(0,a.jsx)(e.strong,{children:"all"})," problems. In this case there\nmay be a solution that is bigger than the one found using the greedy algorithm."]}),"\n",(0,a.jsx)(e.p,{children:"Imagine the following pyramid:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:" 1\n 2 3\n 5 6 7\n 8 9 10 11\n99 13 14 15 16\n"})}),"\n",(0,a.jsx)(e.p,{children:"We start at the top:"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:["Current cell: ",(0,a.jsx)(e.code,{children:"1"}),", we can choose from ",(0,a.jsx)(e.code,{children:"2"})," and ",(0,a.jsx)(e.code,{children:"3"}),", ",(0,a.jsx)(e.code,{children:"3"})," looks better, so we\nchoose it."]}),"\n",(0,a.jsxs)(e.li,{children:["Current cell: ",(0,a.jsx)(e.code,{children:"3"}),", we can choose from ",(0,a.jsx)(e.code,{children:"6"})," and ",(0,a.jsx)(e.code,{children:"7"}),", ",(0,a.jsx)(e.code,{children:"7"})," looks better, so we\nchoose it."]}),"\n",(0,a.jsxs)(e.li,{children:["Current cell: ",(0,a.jsx)(e.code,{children:"7"}),", we can choose from ",(0,a.jsx)(e.code,{children:"10"})," and ",(0,a.jsx)(e.code,{children:"11"}),", ",(0,a.jsx)(e.code,{children:"11"})," looks better, so we\nchoose it."]}),"\n",(0,a.jsxs)(e.li,{children:["Current cell: ",(0,a.jsx)(e.code,{children:"11"}),", we can choose from ",(0,a.jsx)(e.code,{children:"15"})," and ",(0,a.jsx)(e.code,{children:"16"}),", ",(0,a.jsx)(e.code,{children:"16"})," looks better, so\nwe choose it."]}),"\n"]}),"\n",(0,a.jsxs)(e.p,{children:["Our final sum is: ",(0,a.jsx)(e.code,{children:"1 + 3 + 7 + 11 + 16 = 38"}),", but in the bottom left cell we\nhave a ",(0,a.jsx)(e.code,{children:"99"})," that is bigger than our whole sum."]}),"\n",(0,a.jsx)(e.admonition,{type:"tip",children:(0,a.jsx)(e.p,{children:"Dijkstra's algorithm is a greedy algorithm too, try to think why it is correct."})}),"\n",(0,a.jsx)(e.h2,{id:"top-down-dp",children:"Top-down DP"}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.em,{children:"Top-down dynamic programming"})," is probably the most common approach, since (at\nleast looks like) is the easiest to implement. The whole point is avoiding the\nunnecessary computations that we have already done."]}),"\n",(0,a.jsxs)(e.p,{children:["In our case, we can use our na\xefve solution and put a ",(0,a.jsx)(e.em,{children:"cache"})," on top of it that\nwill make sure, we don't do unnecessary calculations."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"// This \u201cstructure\u201d is required, since I have decided to use \u2039TreeMap\u203a which\n// requires the ordering on the keys. It represents one position in the pyramid.\nrecord Position(int row, int col) implements Comparable {\n public int compareTo(Position r) {\n if (row != r.row) {\n return Integer.valueOf(row).compareTo(r.row);\n }\n\n if (col != r.col) {\n return Integer.valueOf(col).compareTo(r.col);\n }\n\n return 0;\n }\n}\n\npublic static int longestSlideDown(\n int[][] pyramid,\n TreeMap cache,\n Position position) {\n int row = position.row;\n int col = position.col;\n\n if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {\n // BASE: out of bounds\n return Integer.MIN_VALUE;\n }\n\n if (row == pyramid.length - 1) {\n // BASE: bottom of the pyramid\n return pyramid[position.row][position.col];\n }\n\n if (!cache.containsKey(position)) {\n // We haven't computed the position yet, so we run the same \u201cformula\u201d as\n // in the na\xefve version \xbband\xab we put calculated slide into the cache.\n // Next time we want the slide down from given position, it will be just\n // retrieved from the cache.\n int slideDown = Math.max(\n longestSlideDown(pyramid, cache, new Position(row + 1, col)),\n longestSlideDown(pyramid, cache, new Position(row + 1, col + 1)));\n cache.put(position, pyramid[row][col] + slideDown);\n }\n\n return cache.get(position);\n}\n\npublic static int longestSlideDown(int[][] pyramid) {\n // At the beginning we need to create a cache and share it across the calls.\n TreeMap cache = new TreeMap<>();\n return longestSlideDown(pyramid, cache, new Position(0, 0));\n}\n"})}),"\n",(0,a.jsxs)(e.p,{children:["You have probably noticed that ",(0,a.jsx)(e.code,{children:"record Position"})," have appeared. Since we are\ncaching the already computed values, we need a \u201creasonable\u201d key. In this case we\nshare the cache only for one ",(0,a.jsx)(e.em,{children:"run"})," (i.e. pyramid) of the ",(0,a.jsx)(e.code,{children:"longestSlideDown"}),", so\nwe can cache just with the indices within the pyramid, i.e. the ",(0,a.jsx)(e.code,{children:"Position"}),"."]}),"\n",(0,a.jsx)(e.admonition,{title:"Record",type:"tip",children:(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.em,{children:"Record"})," is relatively new addition to the Java language. It is basically an\nimmutable structure with implicitly defined ",(0,a.jsx)(e.code,{children:".equals()"}),", ",(0,a.jsx)(e.code,{children:".hashCode()"}),",\n",(0,a.jsx)(e.code,{children:".toString()"})," and getters for the attributes."]})}),"\n",(0,a.jsxs)(e.p,{children:["Because of the choice of ",(0,a.jsx)(e.code,{children:"TreeMap"}),", we had to additionally define the ordering\non it."]}),"\n",(0,a.jsxs)(e.p,{children:["In the ",(0,a.jsx)(e.code,{children:"longestSlideDown"})," you can notice that the computation which used to be\nat the end of the na\xefve version above, is now wrapped in an ",(0,a.jsx)(e.code,{children:"if"})," statement that\nchecks for the presence of the position in the cache and computes the slide down\njust when it's needed."]}),"\n",(0,a.jsx)(e.h3,{id:"time-complexity-2",children:"Time complexity"}),"\n",(0,a.jsx)(e.p,{children:"If you think that evaluating time complexity for this approach is a bit more\ntricky, you are right. Keeping the cache in mind, it is not the easiest thing\nto do. However there are some observations that might help us figure this out:"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsx)(e.li,{children:"Slide down from each position is calculated only once."}),"\n",(0,a.jsx)(e.li,{children:"Once calculated, we use the result from the cache."}),"\n"]}),"\n",(0,a.jsxs)(e.p,{children:["Knowing this, we still cannot, at least easily, describe the time complexity of\nfinding the best slide down from a specific position, ",(0,a.jsx)(e.strong,{children:"but"})," we can bound it\nfrom above for the ",(0,a.jsx)(e.strong,{children:"whole"})," run from the top. Now the question is how we can do\nthat!"]}),"\n",(0,a.jsxs)(e.p,{children:["Overall we are doing the same things for almost",(0,a.jsx)(e.sup,{children:(0,a.jsx)(e.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," all of the positions within\nthe pyramid:"]}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:["\n",(0,a.jsx)(e.p,{children:"We calculate and store it (using the partial results stored in cache). This\nis done only once."}),"\n",(0,a.jsxs)(e.p,{children:["For each calculation we take 2 values from the cache and insert one value.\nBecause we have chosen ",(0,a.jsx)(e.code,{children:"TreeMap"}),", these 3 operations have logarithmic time\ncomplexity and therefore this step is equivalent to ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mn,{children:"3"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsxs)(e.msub,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"})]}),(0,a.jsx)(e.mn,{children:"2"})]}),(0,a.jsx)(e.mi,{children:"n"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"3 \\cdot \\log_2{n}"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6444em"}}),(0,a.jsx)(e.span,{className:"mord",children:"3"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.9386em",verticalAlign:"-0.2441em"}}),(0,a.jsxs)(e.span,{className:"mop",children:[(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.207em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.4559em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.2441em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})]}),"."]}),"\n",(0,a.jsx)(e.p,{children:"However for the sake of simplicity, we are going to account only for the\ninsertion, the reason is rather simple, if we include the 2 retrievals here,\nit will be interleaved with the next step, therefore it is easier to keep the\nretrievals in the following point."}),"\n",(0,a.jsx)(e.admonition,{type:"caution",children:(0,a.jsx)(e.p,{children:"You might have noticed it's still not that easy, cause we're not having full\ncache right from the beginning, but the sum of those logarithms cannot be\nexpressed in a nice way, so taking the upper bound, i.e. expecting the cache\nto be full at all times, is the best option for nice and readable complexity\nof the whole approach."})}),"\n",(0,a.jsxs)(e.p,{children:["Our final upper bound of this work is therefore ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsxs)(e.msub,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"})]}),(0,a.jsx)(e.mn,{children:"2"})]}),(0,a.jsx)(e.mi,{children:"n"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\log_2{n}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.9386em",verticalAlign:"-0.2441em"}}),(0,a.jsxs)(e.span,{className:"mop",children:[(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.207em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.4559em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.2441em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})})]}),"."]}),"\n"]}),"\n",(0,a.jsxs)(e.li,{children:["\n",(0,a.jsxs)(e.p,{children:["We retrieve it from the cache. Same as in first point, but only twice, so we\nget ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsxs)(e.msub,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"})]}),(0,a.jsx)(e.mn,{children:"2"})]}),(0,a.jsx)(e.mi,{children:"n"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"2 \\cdot \\log_2{n}"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6444em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.9386em",verticalAlign:"-0.2441em"}}),(0,a.jsxs)(e.span,{className:"mop",children:[(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.207em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.4559em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.2441em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})]}),"."]}),"\n",(0,a.jsx)(e.admonition,{type:"caution",children:(0,a.jsxs)(e.p,{children:["It's done twice because of the ",(0,a.jsx)(e.code,{children:".containsKey()"})," in the ",(0,a.jsx)(e.code,{children:"if"})," condition."]})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(e.p,{children:"Okay, we have evaluated work done for each of the cells in the pyramid and now\nwe need to put it together."}),"\n",(0,a.jsx)(e.p,{children:"Let's split the time complexity of our solution into two operands:"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(r + s)"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"r"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"r"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"})]})})]})," will represent the ",(0,a.jsx)(e.em,{children:"actual"})," calculation of the cells and ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"s"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"s"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})]})})]})," will represent\nthe additional retrievals on top of the calculation."]}),"\n",(0,a.jsxs)(e.p,{children:["We calculate the values only ",(0,a.jsx)(e.strong,{children:"once"}),", therefore we can safely agree on:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mtable,{rowspacing:"0.25em",columnalign:"right left",columnspacing:"0em",children:(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"r"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"})]})})})]})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\begin{align*}\nr &= n \\cdot \\log{n} \\\\\n\\end{align*}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1.5em",verticalAlign:"-0.5em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsxs)(e.span,{className:"mtable",children:[(0,a.jsx)(e.span,{className:"col-align-r",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"1em"},children:(0,a.jsxs)(e.span,{style:{top:"-3.16em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.5em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"1em"},children:(0,a.jsxs)(e.span,{style:{top:"-3.16em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.5em"},children:(0,a.jsx)(e.span,{})})})]})})]})})]})})]})}),"\n",(0,a.jsxs)(e.p,{children:["What about the ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"s"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"s"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})]})})]})," though? Key observation here is the fact that we have 2\nlookups on the tree in each of them ",(0,a.jsx)(e.strong,{children:"and"})," we do it twice, cause each cell has\nat most 2 parents:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mtable,{rowspacing:"0.25em",columnalign:"right left",columnspacing:"0em",children:[(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"s"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mo,{fence:"true",children:"("}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{fence:"true",children:")"})]})]})})})]}),(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"s"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"4"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"})]})})})]})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\begin{align*}\ns &= n \\cdot 2 \\cdot \\left( 2 \\cdot \\log{n} \\right) \\\\\ns &= 4 \\cdot n \\cdot \\log{n}\n\\end{align*}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"3em",verticalAlign:"-1.25em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsxs)(e.span,{className:"mtable",children:[(0,a.jsx)(e.span,{className:"col-align-r",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.75em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.91em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})})]}),(0,a.jsxs)(e.span,{style:{top:"-2.41em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.25em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.75em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.91em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"minner",children:[(0,a.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:"("}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mclose delimcenter",style:{top:"0em"},children:")"})]})]})]}),(0,a.jsxs)(e.span,{style:{top:"-2.41em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord",children:"4"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.25em"},children:(0,a.jsx)(e.span,{})})})]})})]})})]})})]})}),"\n",(0,a.jsxs)(e.admonition,{type:"tip",children:[(0,a.jsxs)(e.p,{children:["You might've noticed that lookups actually take more time than the construction\nof the results. This is not entirely true, since we have included the\n",(0,a.jsx)(e.code,{children:".containsKey()"})," and ",(0,a.jsx)(e.code,{children:".get()"})," from the ",(0,a.jsx)(e.code,{children:"return"})," statement in the second part."]}),(0,a.jsx)(e.p,{children:"If we were to represent this more precisely, we could've gone with:"}),(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mtable,{rowspacing:"0.25em",columnalign:"right left",columnspacing:"0em",children:[(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"r"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"3"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"})]})})})]}),(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"s"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"})]})})})]})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\begin{align*}\nr &= 3 \\cdot n \\cdot \\log{n} \\\\\ns &= 2 \\cdot n \\cdot \\log{n}\n\\end{align*}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"3em",verticalAlign:"-1.25em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsxs)(e.span,{className:"mtable",children:[(0,a.jsx)(e.span,{className:"col-align-r",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.75em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.91em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"})})]}),(0,a.jsxs)(e.span,{style:{top:"-2.41em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.25em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.75em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.91em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord",children:"3"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]}),(0,a.jsxs)(e.span,{style:{top:"-2.41em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.25em"},children:(0,a.jsx)(e.span,{})})})]})})]})})]})})]})}),(0,a.jsx)(e.p,{children:"On the other hand we are summing both numbers together, therefore in the end it\ndoesn't really matter."}),(0,a.jsxs)(e.p,{children:["(",(0,a.jsx)(e.em,{children:"Feel free to compare the sums of both \u201csplits\u201d."}),")"]})]}),"\n",(0,a.jsxs)(e.p,{children:["And so our final time complexity for the whole ",(0,a.jsx)(e.em,{children:"top-down dynamic programming"}),"\napproach is:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mspace,{linebreak:"newline"}),(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mn,{children:"4"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mspace,{linebreak:"newline"}),(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mn,{children:"5"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mspace,{linebreak:"newline"}),(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(r + s) \\\\\n\\mathcal{O}(n \\cdot \\log{n} + 4 \\cdot n \\cdot \\log{n}) \\\\\n\\mathcal{O}(5 \\cdot n \\cdot \\log{n}) \\\\\n\\mathcal{O}(n \\cdot \\log{n})"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]}),(0,a.jsx)(e.span,{className:"mspace newline"}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6444em"}}),(0,a.jsx)(e.span,{className:"mord",children:"4"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4445em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]}),(0,a.jsx)(e.span,{className:"mspace newline"}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord",children:"5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4445em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]}),(0,a.jsx)(e.span,{className:"mspace newline"}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,a.jsxs)(e.p,{children:["As you can see, this is worse than our ",(0,a.jsx)(e.em,{children:"greedy"})," solution that was incorrect, but\nit's better than the ",(0,a.jsx)(e.em,{children:"na\xefve"})," one."]}),"\n",(0,a.jsx)(e.h3,{id:"memory-complexity",children:"Memory complexity"}),"\n",(0,a.jsxs)(e.p,{children:["With this approach we need to talk about the memory complexity too, because we\nhave introduced cache. If you think that the memory complexity is linear to the\ninput, you are right. We start at the top and try to find each and every slide\ndown. At the end we get the final result for ",(0,a.jsx)(e.code,{children:"new Position(0, 0)"}),", so we need to\ncompute everything below."]}),"\n",(0,a.jsx)(e.p,{children:"That's how we obtain:"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(n)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"n"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"n"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})]})})]})," represents the total amount of cells in the pyramid, i.e."]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsxs)(e.munderover,{children:[(0,a.jsx)(e.mo,{children:"\u2211"}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"0"})]}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"p"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"y"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"r"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"a"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"m"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"i"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"d"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"."}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"l"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"e"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"n"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"g"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"t"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"h"})]}),(0,a.jsx)(e.mo,{children:"\u2212"}),(0,a.jsx)(e.mn,{children:"1"})]})]}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"p"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"y"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"r"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"a"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"m"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"i"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"d"})]}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mo,{fence:"true",children:"["}),(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{fence:"true",children:"]"})]}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"."}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"l"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"e"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"n"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"g"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"t"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"h"})]})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\sum_{y=0}^{\\mathtt{pyramid.length} - 1} \\mathtt{pyramid}\\left[y\\right]\\mathtt{.length}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"3.2709em",verticalAlign:"-1.4032em"}}),(0,a.jsx)(e.span,{className:"mop op-limits",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.8677em"},children:[(0,a.jsxs)(e.span,{style:{top:"-1.8829em",marginLeft:"0em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.05em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsxs)(e.span,{className:"mord mtight",children:[(0,a.jsx)(e.span,{className:"mord mathnormal mtight",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mrel mtight",children:"="}),(0,a.jsx)(e.span,{className:"mord mtight",children:"0"})]})})]}),(0,a.jsxs)(e.span,{style:{top:"-3.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.05em"}}),(0,a.jsx)(e.span,{children:(0,a.jsx)(e.span,{className:"mop op-symbol large-op",children:"\u2211"})})]}),(0,a.jsxs)(e.span,{style:{top:"-4.3666em",marginLeft:"0em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.05em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsxs)(e.span,{className:"mord mtight",children:[(0,a.jsx)(e.span,{className:"mord mtight",children:(0,a.jsx)(e.span,{className:"mord mathtt mtight",children:"pyramid.length"})}),(0,a.jsx)(e.span,{className:"mbin mtight",children:"\u2212"}),(0,a.jsx)(e.span,{className:"mord mtight",children:"1"})]})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.4032em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathtt",children:"pyramid"})}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsxs)(e.span,{className:"minner",children:[(0,a.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:"["}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mclose delimcenter",style:{top:"0em"},children:"]"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathtt",children:".length"})})]})})]})}),"\n",(0,a.jsx)(e.admonition,{type:"caution",children:(0,a.jsxs)(e.p,{children:["If you're wondering whether it's correct because of the second ",(0,a.jsx)(e.code,{children:"if"})," in our\nfunction, your guess is right. However we are expressing the complexity in the\nBachmann-Landau notation, so we care about the ",(0,a.jsx)(e.strong,{children:"upper bound"}),", not the exact\nnumber."]})}),"\n",(0,a.jsxs)(e.admonition,{title:"Can this be optimized?",type:"tip",children:[(0,a.jsx)(e.p,{children:"Yes, it can! Try to think about a way, how can you minimize the memory\ncomplexity of this approach. I'll give you a hint:"}),(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(rows)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})})]}),"\n",(0,a.jsx)(e.h2,{id:"bottom-up-dp",children:"Bottom-up DP"}),"\n",(0,a.jsxs)(e.p,{children:["If you try to think in depth about the top-down DP solution, you might notice\nthat the ",(0,a.jsx)(e.em,{children:"core"})," of it stands on caching the calculations that have been already\ndone on the lower \u201clevels\u201d of the pyramid. Our bottom-up implementation will be\nusing this fact!"]}),"\n",(0,a.jsxs)(e.admonition,{type:"tip",children:[(0,a.jsxs)(e.p,{children:["As I have said in the ",(0,a.jsx)(e.em,{children:"top-down DP"})," section, it is the easiest way to implement\nDP (unless the cached function has complicated parameters, in that case it might\nget messy)."]}),(0,a.jsx)(e.p,{children:"Bottom-up dynamic programming can be more effective, but may be more complicated\nto implement right from the beginning."})]}),"\n",(0,a.jsx)(e.p,{children:"Let's see how we can implement it:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid) {\n // In the beginning we declare new array. At this point it is easier to just\n // work with the one dimension, i.e. just allocating the space for the rows.\n int[][] slideDowns = new int[pyramid.length][];\n\n // Bottom row gets just copied, there's nothing else to do\u2026 It's the base\n // case.\n slideDowns[pyramid.length - 1] = Arrays.copyOf(pyramid[pyramid.length - 1],\n pyramid[pyramid.length - 1].length);\n\n // Then we need to propagate the found slide downs for each of the levels\n // above.\n for (int y = pyramid.length - 2; y >= 0; --y) {\n // We start by copying the values lying in the row we're processing.\n // They get included in the final sum and we need to allocate the space\n // for the precalculated slide downs anyways.\n int[] row = Arrays.copyOf(pyramid[y], pyramid[y].length);\n\n // At this we just need to \u201cfetch\u201d the partial results from \u201cneighbours\u201d\n for (int x = 0; x < row.length; ++x) {\n // We look under our position, since we expect the rows to get\n // shorter, we can safely assume such position exists.\n int under = slideDowns[y + 1][x];\n\n // Then we have a look to the right, such position doesn't have to\n // exist, e.g. on the right edge, so we validate the index, and if\n // it doesn't exist, we just assign minimum of the \u2039int\u203a which makes\n // sure that it doesn't get picked in the \u2039Math.max()\u203a call.\n int toRight = x + 1 < slideDowns[y + 1].length\n ? slideDowns[y + 1][x + 1]\n : Integer.MIN_VALUE;\n\n // Finally we add the best choice at this point.\n row[x] += Math.max(under, toRight);\n }\n\n // And save the row we've just calculated partial results for to the\n // \u201ctable\u201d.\n slideDowns[y] = row;\n }\n\n // At the end we can find our seeked slide down at the top cell.\n return slideDowns[0][0];\n}\n"})}),"\n",(0,a.jsx)(e.p,{children:"I've tried to explain the code as much as possible within the comments, since it\nmight be more beneficial to see right next to the \u201coffending\u201d lines."}),"\n",(0,a.jsxs)(e.p,{children:["As you can see, in this approach we go from the other side",(0,a.jsx)(e.sup,{children:(0,a.jsx)(e.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),", the bottom of\nthe pyramid and propagate the partial results up."]}),"\n",(0,a.jsxs)(e.admonition,{type:"info",children:[(0,a.jsxs)(e.mdxAdmonitionTitle,{children:["How is this different from the ",(0,a.jsx)(e.em,{children:"greedy"})," solution???"]}),(0,a.jsxs)(e.p,{children:["If you try to compare them, you might find a very noticable difference. The\ngreedy approach is going from the top to the bottom without ",(0,a.jsx)(e.strong,{children:"any"})," knowledge of\nwhat's going on below. On the other hand, bottom-up DP is going from the bottom\n(",(0,a.jsx)(e.em,{children:"DUH\u2026"}),") and ",(0,a.jsx)(e.strong,{children:"propagates"})," the partial results to the top. The propagation is\nwhat makes sure that at the top I don't choose the best ",(0,a.jsx)(e.strong,{children:"local"})," choice, but\nthe best ",(0,a.jsx)(e.strong,{children:"overall"})," result I can achieve."]})]}),"\n",(0,a.jsx)(e.h3,{id:"time-complexity-3",children:"Time complexity"}),"\n",(0,a.jsx)(e.p,{children:"Time complexity of this solution is rather simple. We allocate an array for the\nrows and then for each row, we copy it and adjust the partial results. Doing\nthis we get:"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(rows + 2n)"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,a.jsx)(e.p,{children:"Of course, this is an upper bound, since we iterate through the bottom row only\nonce."}),"\n",(0,a.jsx)(e.h3,{id:"memory-complexity-1",children:"Memory complexity"}),"\n",(0,a.jsxs)(e.p,{children:["We're allocating an array for the pyramid ",(0,a.jsx)(e.strong,{children:"again"})," for our partial results, so\nwe get:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(n)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})}),"\n",(0,a.jsxs)(e.admonition,{type:"tip",children:[(0,a.jsx)(e.p,{children:"If we were writing this in C++ or Rust, we could've avoided that, but not\nreally."}),(0,a.jsxs)(e.p,{children:["C++ would allow us to ",(0,a.jsx)(e.strong,{children:"copy"})," the pyramid rightaway into the parameter, so we\nwould be able to directly change it. However it's still a copy, even though we\ndon't need to allocate anything ourselves. It's just implicitly done for us."]}),(0,a.jsxs)(e.p,{children:["Rust is more funny in this case. If the pyramids weren't used after the call of\n",(0,a.jsx)(e.code,{children:"longest_slide_down"}),", it would simply ",(0,a.jsx)(e.strong,{children:"move"})," them into the functions. If they\nwere used afterwards, the compiler would force you to either borrow it, or\n",(0,a.jsx)(e.em,{children:"clone-and-move"})," for the function."]}),(0,a.jsx)(e.hr,{}),(0,a.jsxs)(e.p,{children:["Since we're doing it in Java, we get a reference to the ",(0,a.jsx)(e.em,{children:"original"})," array and we\ncan't do whatever we want with it."]})]}),"\n",(0,a.jsx)(e.h2,{id:"summary",children:"Summary"}),"\n",(0,a.jsxs)(e.p,{children:["And we've finally reached the end. We have seen 4 different \u201csolutions\u201d",(0,a.jsx)(e.sup,{children:(0,a.jsx)(e.a,{href:"#user-content-fn-4",id:"user-content-fnref-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"4"})})," of\nthe same problem using different approaches. Different approaches follow the\norder in which you might come up with them, each approach influences its\nsuccessor and represents the way we can enhance the existing implementation."]}),"\n",(0,a.jsx)(e.hr,{}),"\n",(0,a.jsx)(e.admonition,{title:"source",type:"info",children:(0,a.jsxs)(e.p,{children:["You can find source code referenced in the text\n",(0,a.jsx)(e.a,{href:"pathname:///files/algorithms/recursion/pyramid-slide-down.tar.gz",children:"here"}),"."]})}),"\n",(0,a.jsxs)(e.section,{"data-footnotes":!0,className:"footnotes",children:[(0,a.jsx)(e.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{id:"user-content-fn-1",children:["\n",(0,a.jsxs)(e.p,{children:["cause why not, right!? ",(0,a.jsx)(e.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(e.li,{id:"user-content-fn-2",children:["\n",(0,a.jsxs)(e.p,{children:["except the bottom row ",(0,a.jsx)(e.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(e.li,{id:"user-content-fn-3",children:["\n",(0,a.jsxs)(e.p,{children:["definitely not an RHCP reference ","\ud83d\ude09 ",(0,a.jsx)(e.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(e.li,{id:"user-content-fn-4",children:["\n",(0,a.jsxs)(e.p,{children:["one was not correct, thus the quotes ",(0,a.jsx)(e.a,{href:"#user-content-fnref-4","data-footnote-backref":"","aria-label":"Back to reference 4",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function o(s={}){const{wrapper:e}={...(0,i.a)(),...s.components};return e?(0,a.jsx)(e,{...s,children:(0,a.jsx)(h,{...s})}):h(s)}},11151:(s,e,n)=>{n.d(e,{Z:()=>r,a:()=>t});var a=n(67294);const i={},l=a.createContext(i);function t(s){const e=a.useContext(l);return a.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function r(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(i):s.components||i:t(s.components),a.createElement(l.Provider,{value:e},s.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[2619],{14457:(s,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>t,default:()=>o,frontMatter:()=>l,metadata:()=>r,toc:()=>m});var a=n(85893),i=n(11151);const l={id:"pyramid-slide-down",title:"Introduction to dynamic programming",description:"Solving a problem in different ways.\n",tags:["java","recursion","exponential","greedy","dynamic-programming","top-down-dp","bottom-up-dp"],last_updated:{date:new Date("2023-08-17T00:00:00.000Z")}},t=void 0,r={id:"recursion/pyramid-slide-down",title:"Introduction to dynamic programming",description:"Solving a problem in different ways.\n",source:"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down.md",sourceDirName:"04-recursion",slug:"/recursion/pyramid-slide-down",permalink:"/algorithms/recursion/pyramid-slide-down",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/04-recursion/2023-08-17-pyramid-slide-down.md",tags:[{label:"java",permalink:"/algorithms/tags/java"},{label:"recursion",permalink:"/algorithms/tags/recursion"},{label:"exponential",permalink:"/algorithms/tags/exponential"},{label:"greedy",permalink:"/algorithms/tags/greedy"},{label:"dynamic-programming",permalink:"/algorithms/tags/dynamic-programming"},{label:"top-down-dp",permalink:"/algorithms/tags/top-down-dp"},{label:"bottom-up-dp",permalink:"/algorithms/tags/bottom-up-dp"}],version:"current",lastUpdatedAt:1701200735,formattedLastUpdatedAt:"Nov 28, 2023",frontMatter:{id:"pyramid-slide-down",title:"Introduction to dynamic programming",description:"Solving a problem in different ways.\n",tags:["java","recursion","exponential","greedy","dynamic-programming","top-down-dp","bottom-up-dp"],last_updated:{date:"2023-08-17T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Recursion and backtracking with Robot Karel",permalink:"/algorithms/recursion/karel-1"},next:{title:"Red-Black Trees",permalink:"/algorithms/category/red-black-trees"}},c={},m=[{value:"Problem",id:"problem",level:2},{value:"Solving the problem",id:"solving-the-problem",level:2},{value:"Na\xefve solution",id:"na\xefve-solution",level:2},{value:"Time complexity",id:"time-complexity",level:3},{value:"Greedy solution",id:"greedy-solution",level:2},{value:"Time complexity",id:"time-complexity-1",level:3},{value:"Running the tests",id:"running-the-tests",level:3},{value:"Top-down DP",id:"top-down-dp",level:2},{value:"Time complexity",id:"time-complexity-2",level:3},{value:"Memory complexity",id:"memory-complexity",level:3},{value:"Bottom-up DP",id:"bottom-up-dp",level:2},{value:"Time complexity",id:"time-complexity-3",level:3},{value:"Memory complexity",id:"memory-complexity-1",level:3},{value:"Summary",id:"summary",level:2}];function h(s){const e={a:"a",admonition:"admonition",annotation:"annotation",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",li:"li",math:"math",mdxAdmonitionTitle:"mdxAdmonitionTitle",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",mspace:"mspace",mstyle:"mstyle",msub:"msub",msup:"msup",mtable:"mtable",mtd:"mtd",mtext:"mtext",mtr:"mtr",munderover:"munderover",ol:"ol",p:"p",pre:"pre",section:"section",semantics:"semantics",span:"span",strong:"strong",sup:"sup",...(0,i.a)(),...s.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.p,{children:"In this post we will try to solve one problem in different ways."}),"\n",(0,a.jsx)(e.h2,{id:"problem",children:"Problem"}),"\n",(0,a.jsxs)(e.p,{children:["The problem we are going to solve is one of ",(0,a.jsx)(e.em,{children:"CodeWars"})," katas and is called\n",(0,a.jsx)(e.a,{href:"https://www.codewars.com/kata/551f23362ff852e2ab000037",children:"Pyramid Slide Down"}),"."]}),"\n",(0,a.jsxs)(e.p,{children:["We are given a 2D array of integers and we are to find the ",(0,a.jsx)(e.em,{children:"slide down"}),".\n",(0,a.jsx)(e.em,{children:"Slide down"})," is a maximum sum of consecutive numbers from the top to the bottom."]}),"\n",(0,a.jsx)(e.p,{children:"Let's have a look at few examples. Consider the following pyramid:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:" 3\n 7 4\n 2 4 6\n8 5 9 3\n"})}),"\n",(0,a.jsx)(e.p,{children:"This pyramid has following slide down:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:" *3\n *7 4\n 2 *4 6\n8 5 *9 3\n"})}),"\n",(0,a.jsxs)(e.p,{children:["And its value is ",(0,a.jsx)(e.code,{children:"23"}),"."]}),"\n",(0,a.jsxs)(e.p,{children:["We can also have a look at a ",(0,a.jsx)(e.em,{children:"bigger"})," example:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:" 75\n 95 64\n 17 47 82\n 18 35 87 10\n 20 4 82 47 65\n 19 1 23 3 34\n 88 2 77 73 7 63 67\n 99 65 4 28 6 16 70 92\n 41 41 26 56 83 40 80 70 33\n 41 48 72 33 47 32 37 16 94 29\n 53 71 44 65 25 43 91 52 97 51 14\n 70 11 33 28 77 73 17 78 39 68 17 57\n 91 71 52 38 17 14 91 43 58 50 27 29 48\n 63 66 4 68 89 53 67 30 73 16 69 87 40 31\n 4 62 98 27 23 9 70 98 73 93 38 53 60 4 23\n"})}),"\n",(0,a.jsxs)(e.p,{children:["Slide down in this case is equal to ",(0,a.jsx)(e.code,{children:"1074"}),"."]}),"\n",(0,a.jsx)(e.h2,{id:"solving-the-problem",children:"Solving the problem"}),"\n",(0,a.jsx)(e.admonition,{type:"caution",children:(0,a.jsxs)(e.p,{children:["I will describe the following ways you can approach this problem and implement\nthem in ",(0,a.jsx)(e.em,{children:"Java"}),(0,a.jsx)(e.sup,{children:(0,a.jsx)(e.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]})}),"\n",(0,a.jsxs)(e.p,{children:["For all of the following solutions I will be using basic ",(0,a.jsx)(e.code,{children:"main"})," function that\nwill output ",(0,a.jsx)(e.code,{children:"true"}),"/",(0,a.jsx)(e.code,{children:"false"})," based on the expected output of our algorithm. Any\nother differences will lie only in the solutions of the problem. You can see the\n",(0,a.jsx)(e.code,{children:"main"})," here:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:'public static void main(String[] args) {\n System.out.print("Test #1: ");\n System.out.println(longestSlideDown(new int[][] {\n { 3 },\n { 7, 4 },\n { 2, 4, 6 },\n { 8, 5, 9, 3 }\n }) == 23 ? "passed" : "failed");\n\n System.out.print("Test #2: ");\n System.out.println(longestSlideDown(new int[][] {\n { 75 },\n { 95, 64 },\n { 17, 47, 82 },\n { 18, 35, 87, 10 },\n { 20, 4, 82, 47, 65 },\n { 19, 1, 23, 75, 3, 34 },\n { 88, 2, 77, 73, 7, 63, 67 },\n { 99, 65, 4, 28, 6, 16, 70, 92 },\n { 41, 41, 26, 56, 83, 40, 80, 70, 33 },\n { 41, 48, 72, 33, 47, 32, 37, 16, 94, 29 },\n { 53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14 },\n { 70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57 },\n { 91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48 },\n { 63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31 },\n { 4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23 },\n }) == 1074 ? "passed" : "failed");\n}\n'})}),"\n",(0,a.jsx)(e.h2,{id:"na\xefve-solution",children:"Na\xefve solution"}),"\n",(0,a.jsx)(e.p,{children:"Our na\xefve solution consists of trying out all the possible slides and finding\nthe one with maximum sum."}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid, int row, int col) {\n if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {\n // BASE: We have gotten out of bounds, there's no reasonable value to\n // return, so we just return the \u2039MIN_VALUE\u203a to ensure that it cannot\n // be maximum.\n return Integer.MIN_VALUE;\n }\n\n if (row == pyramid.length - 1) {\n // BASE: Bottom of the pyramid, we just return the value, there's\n // nowhere to slide anymore.\n return pyramid[row][col];\n }\n\n // Otherwise we account for the current position and return maximum of the\n // available \u201cslides\u201d.\n return pyramid[row][col] + Math.max(\n longestSlideDown(pyramid, row + 1, col),\n longestSlideDown(pyramid, row + 1, col + 1));\n}\n\npublic static int longestSlideDown(int[][] pyramid) {\n // We start the slide in the top cell of the pyramid.\n return longestSlideDown(pyramid, 0, 0);\n}\n"})}),"\n",(0,a.jsx)(e.p,{children:"As you can see, we have 2 overloads:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"int longestSlideDown(int[][] pyramid);\nint longestSlideDown(int[][] pyramid, int row, int col);\n"})}),"\n",(0,a.jsxs)(e.p,{children:["First one is used as a ",(0,a.jsx)(e.em,{children:"public interface"})," to the solution, you just pass in the\npyramid itself. Second one is the recursive \u201calgorithm\u201d that finds the slide\ndown."]}),"\n",(0,a.jsxs)(e.p,{children:["It is a relatively simple solution\u2026 There's nothing to do at the bottom of the\npyramid, so we just return the value in the ",(0,a.jsx)(e.em,{children:"cell"}),". Otherwise we add it and try\nto slide down the available cells below the current row."]}),"\n",(0,a.jsx)(e.h3,{id:"time-complexity",children:"Time complexity"}),"\n",(0,a.jsx)(e.p,{children:"If you get the source code and run it yourself, it runs rather fine\u2026 I hope you\nare wondering about the time complexity of the proposed solution and, since it\nreally is a na\xefve solution, the time complexity is pretty bad. Let's find the\nworst case scenario."}),"\n",(0,a.jsx)(e.p,{children:"Let's start with the first overload:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid) {\n return longestSlideDown(pyramid, 0, 0);\n}\n"})}),"\n",(0,a.jsxs)(e.p,{children:["There's not much to do here, so we can safely say that the time complexity of\nthis function is bounded by ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T(n)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]}),", where ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"T"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6833em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"})]})})]})," is our second overload. This\ndoesn't tell us anything, so let's move on to the second overload where we are\ngoing to define the ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T(n)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})," function."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid, int row, int col) {\n if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {\n // BASE: We have gotten out of bounds, there's no reasonable value to\n // return, so we just return the \u2039MIN_VALUE\u203a to ensure that it cannot\n // be maximum.\n return Integer.MIN_VALUE;\n }\n\n if (row == pyramid.length - 1) {\n // BASE: Bottom of the pyramid, we just return the value, there's\n // nowhere to slide anymore.\n return pyramid[row][col];\n }\n\n // Otherwise we account for the current position and return maximum of the\n // available \u201cslides\u201d.\n return pyramid[row][col] + Math.max(\n longestSlideDown(pyramid, row + 1, col),\n longestSlideDown(pyramid, row + 1, col + 1));\n}\n"})}),"\n",(0,a.jsxs)(e.p,{children:["Fun fact is that the whole \u201calgorithm\u201d consists of just 2 ",(0,a.jsx)(e.code,{children:"return"})," statements\nand nothing else. Let's dissect them!"]}),"\n",(0,a.jsxs)(e.p,{children:["First ",(0,a.jsx)(e.code,{children:"return"})," statement is the base case, so it has a constant time complexity."]}),"\n",(0,a.jsxs)(e.p,{children:["Second one a bit tricky. We add two numbers together, which we'll consider as\nconstant, but for the right part of the expression we take maximum from the left\nand right paths. OK\u2026 So what happens? We evaluate the ",(0,a.jsx)(e.code,{children:"longestSlideDown"})," while\nchoosing the under and right both. They are separate computations though, so we\nare branching from each call of ",(0,a.jsx)(e.code,{children:"longestSlideDown"}),", unless it's a base case."]}),"\n",(0,a.jsx)(e.p,{children:"What does that mean for us then? We basically get"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mo,{fence:"true",children:"{"}),(0,a.jsxs)(e.mtable,{rowspacing:"0.36em",columnalign:"left left",columnspacing:"1em",children:[(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"false",children:(0,a.jsx)(e.mn,{children:"1"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"false",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mtext,{children:",\xa0if\xa0"}),(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"})]})})})]}),(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"false",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mn,{children:"1"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mn,{children:"1"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"false",children:(0,a.jsx)(e.mtext,{children:",\xa0otherwise"})})})]})]})]})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T(y) =\n\\begin{cases}\n1 & \\text{, if } y = rows \\\\\n1 + 2 \\cdot T(y + 1) & \\text{, otherwise}\n\\end{cases}"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mclose",children:")"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"3em",verticalAlign:"-1.25em"}}),(0,a.jsxs)(e.span,{className:"minner",children:[(0,a.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:(0,a.jsx)(e.span,{className:"delimsizing size4",children:"{"})}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsxs)(e.span,{className:"mtable",children:[(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.69em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.69em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.008em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord",children:"1"})})]}),(0,a.jsxs)(e.span,{style:{top:"-2.25em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.008em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord",children:"1"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord",children:"1"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.19em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"arraycolsep",style:{width:"1em"}}),(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.69em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.69em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.008em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord text",children:(0,a.jsx)(e.span,{className:"mord",children:",\xa0if\xa0"})}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})]})]}),(0,a.jsxs)(e.span,{style:{top:"-2.25em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.008em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord text",children:(0,a.jsx)(e.span,{className:"mord",children:",\xa0otherwise"})})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.19em"},children:(0,a.jsx)(e.span,{})})})]})})]})}),(0,a.jsx)(e.span,{className:"mclose nulldelimiter"})]})]})]})]})}),"\n",(0,a.jsx)(e.p,{children:"That looks rather easy to compute, isn't it? If you sum it up, you'll get:"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"T"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mo,{children:"\u2208"}),(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsxs)(e.msup,{children:[(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"})]})]}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"T(rows) \\in \\mathcal{O}(2^{rows})"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"\u2208"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsx)(e.span,{className:"vlist-t",children:(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.7144em"},children:(0,a.jsxs)(e.span,{style:{top:"-3.113em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsxs)(e.span,{className:"mord mtight",children:[(0,a.jsx)(e.span,{className:"mord mathnormal mtight",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal mtight",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal mtight",children:"s"})]})})]})})})})})]}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,a.jsx)(e.p,{children:"If you wonder why, I'll try to describe it intuitively:"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:["In each call to ",(0,a.jsx)(e.code,{children:"longestSlideDown"})," we do some work in constant time,\nregardless of being in the base case. Those are the ",(0,a.jsx)(e.code,{children:"1"}),"s in both cases."]}),"\n",(0,a.jsxs)(e.li,{children:["If we are not in the base case, we move one row down ",(0,a.jsx)(e.strong,{children:"twice"}),". That's how we\nobtained ",(0,a.jsx)(e.code,{children:"2 *"})," and ",(0,a.jsx)(e.code,{children:"y + 1"})," in the ",(0,a.jsx)(e.em,{children:"otherwise"})," case."]}),"\n",(0,a.jsxs)(e.li,{children:["We move row-by-row, so we move down ",(0,a.jsx)(e.code,{children:"y"}),"-times and each call splits to two\nsubtrees."]}),"\n",(0,a.jsxs)(e.li,{children:["Overall, if we were to represent the calls as a tree, we would get a full\nbinary tree of height ",(0,a.jsx)(e.code,{children:"y"}),", in each node we do some work in constant time,\ntherefore we can just sum the ones."]}),"\n"]}),"\n",(0,a.jsx)(e.admonition,{type:"warning",children:(0,a.jsx)(e.p,{children:"It would've been more complicated to get an exact result. In the equation above\nwe are assuming that the width of the pyramid is bound by the height."})}),"\n",(0,a.jsxs)(e.p,{children:["Hopefully we can agree that this is not the best we can do. ","\ud83d\ude09"]}),"\n",(0,a.jsx)(e.h2,{id:"greedy-solution",children:"Greedy solution"}),"\n",(0,a.jsxs)(e.p,{children:["We will try to optimize it a bit. Let's start with a relatively simple ",(0,a.jsx)(e.em,{children:"greedy"}),"\napproach."]}),"\n",(0,a.jsx)(e.admonition,{title:"Greedy algorithms",type:"info",children:(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.em,{children:"Greedy algorithms"})," can be described as algorithms that decide the action on the\noptimal option at the moment."]})}),"\n",(0,a.jsx)(e.p,{children:"We can try to adjust the na\xefve solution. The most problematic part are the\nrecursive calls. Let's apply the greedy approach there:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid, int row, int col) {\n if (row == pyramid.length - 1) {\n // BASE: We're at the bottom\n return pyramid[row][col];\n }\n\n if (col + 1 >= pyramid[row + 1].length\n || pyramid[row + 1][col] > pyramid[row + 1][col + 1]) {\n // If we cannot go right or it's not feasible, we continue to the left.\n return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col);\n }\n\n // Otherwise we just move to the right.\n return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col + 1);\n}\n"})}),"\n",(0,a.jsxs)(e.p,{children:["OK, if we cannot go right ",(0,a.jsx)(e.strong,{children:"or"})," the right path adds smaller value to the sum,\nwe simply go left."]}),"\n",(0,a.jsx)(e.h3,{id:"time-complexity-1",children:"Time complexity"}),"\n",(0,a.jsxs)(e.p,{children:["We have switched from ",(0,a.jsx)(e.em,{children:"adding the maximum"})," to ",(0,a.jsx)(e.em,{children:"following the \u201cbigger\u201d path"}),", so\nwe improved the time complexity tremendously. We just go down the pyramid all\nthe way to the bottom. Therefore we are getting:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(rows)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})}),"\n",(0,a.jsx)(e.p,{children:"We have managed to convert our exponential solution into a linear one."}),"\n",(0,a.jsx)(e.h3,{id:"running-the-tests",children:"Running the tests"}),"\n",(0,a.jsx)(e.p,{children:"However, if we run the tests, we notice that the second test failed:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:"Test #1: passed\nTest #2: failed\n"})}),"\n",(0,a.jsxs)(e.p,{children:["What's going on? Well, we have improved the time complexity, but greedy\nalgorithms are not the ideal solution to ",(0,a.jsx)(e.strong,{children:"all"})," problems. In this case there\nmay be a solution that is bigger than the one found using the greedy algorithm."]}),"\n",(0,a.jsx)(e.p,{children:"Imagine the following pyramid:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:" 1\n 2 3\n 5 6 7\n 8 9 10 11\n99 13 14 15 16\n"})}),"\n",(0,a.jsx)(e.p,{children:"We start at the top:"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:["Current cell: ",(0,a.jsx)(e.code,{children:"1"}),", we can choose from ",(0,a.jsx)(e.code,{children:"2"})," and ",(0,a.jsx)(e.code,{children:"3"}),", ",(0,a.jsx)(e.code,{children:"3"})," looks better, so we\nchoose it."]}),"\n",(0,a.jsxs)(e.li,{children:["Current cell: ",(0,a.jsx)(e.code,{children:"3"}),", we can choose from ",(0,a.jsx)(e.code,{children:"6"})," and ",(0,a.jsx)(e.code,{children:"7"}),", ",(0,a.jsx)(e.code,{children:"7"})," looks better, so we\nchoose it."]}),"\n",(0,a.jsxs)(e.li,{children:["Current cell: ",(0,a.jsx)(e.code,{children:"7"}),", we can choose from ",(0,a.jsx)(e.code,{children:"10"})," and ",(0,a.jsx)(e.code,{children:"11"}),", ",(0,a.jsx)(e.code,{children:"11"})," looks better, so we\nchoose it."]}),"\n",(0,a.jsxs)(e.li,{children:["Current cell: ",(0,a.jsx)(e.code,{children:"11"}),", we can choose from ",(0,a.jsx)(e.code,{children:"15"})," and ",(0,a.jsx)(e.code,{children:"16"}),", ",(0,a.jsx)(e.code,{children:"16"})," looks better, so\nwe choose it."]}),"\n"]}),"\n",(0,a.jsxs)(e.p,{children:["Our final sum is: ",(0,a.jsx)(e.code,{children:"1 + 3 + 7 + 11 + 16 = 38"}),", but in the bottom left cell we\nhave a ",(0,a.jsx)(e.code,{children:"99"})," that is bigger than our whole sum."]}),"\n",(0,a.jsx)(e.admonition,{type:"tip",children:(0,a.jsx)(e.p,{children:"Dijkstra's algorithm is a greedy algorithm too, try to think why it is correct."})}),"\n",(0,a.jsx)(e.h2,{id:"top-down-dp",children:"Top-down DP"}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.em,{children:"Top-down dynamic programming"})," is probably the most common approach, since (at\nleast looks like) is the easiest to implement. The whole point is avoiding the\nunnecessary computations that we have already done."]}),"\n",(0,a.jsxs)(e.p,{children:["In our case, we can use our na\xefve solution and put a ",(0,a.jsx)(e.em,{children:"cache"})," on top of it that\nwill make sure, we don't do unnecessary calculations."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"// This \u201cstructure\u201d is required, since I have decided to use \u2039TreeMap\u203a which\n// requires the ordering on the keys. It represents one position in the pyramid.\nrecord Position(int row, int col) implements Comparable {\n public int compareTo(Position r) {\n if (row != r.row) {\n return Integer.valueOf(row).compareTo(r.row);\n }\n\n if (col != r.col) {\n return Integer.valueOf(col).compareTo(r.col);\n }\n\n return 0;\n }\n}\n\npublic static int longestSlideDown(\n int[][] pyramid,\n TreeMap cache,\n Position position) {\n int row = position.row;\n int col = position.col;\n\n if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {\n // BASE: out of bounds\n return Integer.MIN_VALUE;\n }\n\n if (row == pyramid.length - 1) {\n // BASE: bottom of the pyramid\n return pyramid[position.row][position.col];\n }\n\n if (!cache.containsKey(position)) {\n // We haven't computed the position yet, so we run the same \u201cformula\u201d as\n // in the na\xefve version \xbband\xab we put calculated slide into the cache.\n // Next time we want the slide down from given position, it will be just\n // retrieved from the cache.\n int slideDown = Math.max(\n longestSlideDown(pyramid, cache, new Position(row + 1, col)),\n longestSlideDown(pyramid, cache, new Position(row + 1, col + 1)));\n cache.put(position, pyramid[row][col] + slideDown);\n }\n\n return cache.get(position);\n}\n\npublic static int longestSlideDown(int[][] pyramid) {\n // At the beginning we need to create a cache and share it across the calls.\n TreeMap cache = new TreeMap<>();\n return longestSlideDown(pyramid, cache, new Position(0, 0));\n}\n"})}),"\n",(0,a.jsxs)(e.p,{children:["You have probably noticed that ",(0,a.jsx)(e.code,{children:"record Position"})," have appeared. Since we are\ncaching the already computed values, we need a \u201creasonable\u201d key. In this case we\nshare the cache only for one ",(0,a.jsx)(e.em,{children:"run"})," (i.e. pyramid) of the ",(0,a.jsx)(e.code,{children:"longestSlideDown"}),", so\nwe can cache just with the indices within the pyramid, i.e. the ",(0,a.jsx)(e.code,{children:"Position"}),"."]}),"\n",(0,a.jsx)(e.admonition,{title:"Record",type:"tip",children:(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.em,{children:"Record"})," is relatively new addition to the Java language. It is basically an\nimmutable structure with implicitly defined ",(0,a.jsx)(e.code,{children:".equals()"}),", ",(0,a.jsx)(e.code,{children:".hashCode()"}),",\n",(0,a.jsx)(e.code,{children:".toString()"})," and getters for the attributes."]})}),"\n",(0,a.jsxs)(e.p,{children:["Because of the choice of ",(0,a.jsx)(e.code,{children:"TreeMap"}),", we had to additionally define the ordering\non it."]}),"\n",(0,a.jsxs)(e.p,{children:["In the ",(0,a.jsx)(e.code,{children:"longestSlideDown"})," you can notice that the computation which used to be\nat the end of the na\xefve version above, is now wrapped in an ",(0,a.jsx)(e.code,{children:"if"})," statement that\nchecks for the presence of the position in the cache and computes the slide down\njust when it's needed."]}),"\n",(0,a.jsx)(e.h3,{id:"time-complexity-2",children:"Time complexity"}),"\n",(0,a.jsx)(e.p,{children:"If you think that evaluating time complexity for this approach is a bit more\ntricky, you are right. Keeping the cache in mind, it is not the easiest thing\nto do. However there are some observations that might help us figure this out:"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsx)(e.li,{children:"Slide down from each position is calculated only once."}),"\n",(0,a.jsx)(e.li,{children:"Once calculated, we use the result from the cache."}),"\n"]}),"\n",(0,a.jsxs)(e.p,{children:["Knowing this, we still cannot, at least easily, describe the time complexity of\nfinding the best slide down from a specific position, ",(0,a.jsx)(e.strong,{children:"but"})," we can bound it\nfrom above for the ",(0,a.jsx)(e.strong,{children:"whole"})," run from the top. Now the question is how we can do\nthat!"]}),"\n",(0,a.jsxs)(e.p,{children:["Overall we are doing the same things for almost",(0,a.jsx)(e.sup,{children:(0,a.jsx)(e.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," all of the positions within\nthe pyramid:"]}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:["\n",(0,a.jsx)(e.p,{children:"We calculate and store it (using the partial results stored in cache). This\nis done only once."}),"\n",(0,a.jsxs)(e.p,{children:["For each calculation we take 2 values from the cache and insert one value.\nBecause we have chosen ",(0,a.jsx)(e.code,{children:"TreeMap"}),", these 3 operations have logarithmic time\ncomplexity and therefore this step is equivalent to ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mn,{children:"3"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsxs)(e.msub,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"})]}),(0,a.jsx)(e.mn,{children:"2"})]}),(0,a.jsx)(e.mi,{children:"n"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"3 \\cdot \\log_2{n}"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6444em"}}),(0,a.jsx)(e.span,{className:"mord",children:"3"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.9386em",verticalAlign:"-0.2441em"}}),(0,a.jsxs)(e.span,{className:"mop",children:[(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.207em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.4559em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.2441em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})]}),"."]}),"\n",(0,a.jsx)(e.p,{children:"However for the sake of simplicity, we are going to account only for the\ninsertion, the reason is rather simple, if we include the 2 retrievals here,\nit will be interleaved with the next step, therefore it is easier to keep the\nretrievals in the following point."}),"\n",(0,a.jsx)(e.admonition,{type:"caution",children:(0,a.jsx)(e.p,{children:"You might have noticed it's still not that easy, cause we're not having full\ncache right from the beginning, but the sum of those logarithms cannot be\nexpressed in a nice way, so taking the upper bound, i.e. expecting the cache\nto be full at all times, is the best option for nice and readable complexity\nof the whole approach."})}),"\n",(0,a.jsxs)(e.p,{children:["Our final upper bound of this work is therefore ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsxs)(e.msub,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"})]}),(0,a.jsx)(e.mn,{children:"2"})]}),(0,a.jsx)(e.mi,{children:"n"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\log_2{n}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.9386em",verticalAlign:"-0.2441em"}}),(0,a.jsxs)(e.span,{className:"mop",children:[(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.207em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.4559em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.2441em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})})]}),"."]}),"\n"]}),"\n",(0,a.jsxs)(e.li,{children:["\n",(0,a.jsxs)(e.p,{children:["We retrieve it from the cache. Same as in first point, but only twice, so we\nget ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsxs)(e.msub,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"})]}),(0,a.jsx)(e.mn,{children:"2"})]}),(0,a.jsx)(e.mi,{children:"n"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"2 \\cdot \\log_2{n}"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6444em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.9386em",verticalAlign:"-0.2441em"}}),(0,a.jsxs)(e.span,{className:"mop",children:[(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.207em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.4559em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.2441em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})]}),"."]}),"\n",(0,a.jsx)(e.admonition,{type:"caution",children:(0,a.jsxs)(e.p,{children:["It's done twice because of the ",(0,a.jsx)(e.code,{children:".containsKey()"})," in the ",(0,a.jsx)(e.code,{children:"if"})," condition."]})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(e.p,{children:"Okay, we have evaluated work done for each of the cells in the pyramid and now\nwe need to put it together."}),"\n",(0,a.jsx)(e.p,{children:"Let's split the time complexity of our solution into two operands:"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(r + s)"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"r"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"r"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"})]})})]})," will represent the ",(0,a.jsx)(e.em,{children:"actual"})," calculation of the cells and ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"s"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"s"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})]})})]})," will represent\nthe additional retrievals on top of the calculation."]}),"\n",(0,a.jsxs)(e.p,{children:["We calculate the values only ",(0,a.jsx)(e.strong,{children:"once"}),", therefore we can safely agree on:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mtable,{rowspacing:"0.25em",columnalign:"right left",columnspacing:"0em",children:(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"r"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"})]})})})]})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\begin{align*}\nr &= n \\cdot \\log{n} \\\\\n\\end{align*}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1.5em",verticalAlign:"-0.5em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsxs)(e.span,{className:"mtable",children:[(0,a.jsx)(e.span,{className:"col-align-r",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"1em"},children:(0,a.jsxs)(e.span,{style:{top:"-3.16em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.5em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"1em"},children:(0,a.jsxs)(e.span,{style:{top:"-3.16em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.5em"},children:(0,a.jsx)(e.span,{})})})]})})]})})]})})]})}),"\n",(0,a.jsxs)(e.p,{children:["What about the ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"s"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"s"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})]})})]})," though? Key observation here is the fact that we have 2\nlookups on the tree in each of them ",(0,a.jsx)(e.strong,{children:"and"})," we do it twice, cause each cell has\nat most 2 parents:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mtable,{rowspacing:"0.25em",columnalign:"right left",columnspacing:"0em",children:[(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"s"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mo,{fence:"true",children:"("}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{fence:"true",children:")"})]})]})})})]}),(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"s"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"4"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"})]})})})]})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\begin{align*}\ns &= n \\cdot 2 \\cdot \\left( 2 \\cdot \\log{n} \\right) \\\\\ns &= 4 \\cdot n \\cdot \\log{n}\n\\end{align*}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"3em",verticalAlign:"-1.25em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsxs)(e.span,{className:"mtable",children:[(0,a.jsx)(e.span,{className:"col-align-r",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.75em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.91em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})})]}),(0,a.jsxs)(e.span,{style:{top:"-2.41em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.25em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.75em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.91em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"minner",children:[(0,a.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:"("}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mclose delimcenter",style:{top:"0em"},children:")"})]})]})]}),(0,a.jsxs)(e.span,{style:{top:"-2.41em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord",children:"4"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.25em"},children:(0,a.jsx)(e.span,{})})})]})})]})})]})})]})}),"\n",(0,a.jsxs)(e.admonition,{type:"tip",children:[(0,a.jsxs)(e.p,{children:["You might've noticed that lookups actually take more time than the construction\nof the results. This is not entirely true, since we have included the\n",(0,a.jsx)(e.code,{children:".containsKey()"})," and ",(0,a.jsx)(e.code,{children:".get()"})," from the ",(0,a.jsx)(e.code,{children:"return"})," statement in the second part."]}),(0,a.jsx)(e.p,{children:"If we were to represent this more precisely, we could've gone with:"}),(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mtable,{rowspacing:"0.25em",columnalign:"right left",columnspacing:"0em",children:[(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"r"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"3"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"})]})})})]}),(0,a.jsxs)(e.mtr,{children:[(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsx)(e.mi,{children:"s"})})}),(0,a.jsx)(e.mtd,{children:(0,a.jsx)(e.mstyle,{scriptlevel:"0",displaystyle:"true",children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mrow,{}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"})]})})})]})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\begin{align*}\nr &= 3 \\cdot n \\cdot \\log{n} \\\\\ns &= 2 \\cdot n \\cdot \\log{n}\n\\end{align*}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"3em",verticalAlign:"-1.25em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsxs)(e.span,{className:"mtable",children:[(0,a.jsx)(e.span,{className:"col-align-r",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.75em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.91em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"})})]}),(0,a.jsxs)(e.span,{style:{top:"-2.41em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.25em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"col-align-l",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.75em"},children:[(0,a.jsxs)(e.span,{style:{top:"-3.91em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord",children:"3"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]}),(0,a.jsxs)(e.span,{style:{top:"-2.41em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.25em"},children:(0,a.jsx)(e.span,{})})})]})})]})})]})})]})}),(0,a.jsx)(e.p,{children:"On the other hand we are summing both numbers together, therefore in the end it\ndoesn't really matter."}),(0,a.jsxs)(e.p,{children:["(",(0,a.jsx)(e.em,{children:"Feel free to compare the sums of both \u201csplits\u201d."}),")"]})]}),"\n",(0,a.jsxs)(e.p,{children:["And so our final time complexity for the whole ",(0,a.jsx)(e.em,{children:"top-down dynamic programming"}),"\napproach is:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mspace,{linebreak:"newline"}),(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mn,{children:"4"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mspace,{linebreak:"newline"}),(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mn,{children:"5"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"}),(0,a.jsx)(e.mspace,{linebreak:"newline"}),(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.mi,{children:"log"}),(0,a.jsx)(e.mo,{children:"\u2061"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(r + s) \\\\\n\\mathcal{O}(n \\cdot \\log{n} + 4 \\cdot n \\cdot \\log{n}) \\\\\n\\mathcal{O}(5 \\cdot n \\cdot \\log{n}) \\\\\n\\mathcal{O}(n \\cdot \\log{n})"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]}),(0,a.jsx)(e.span,{className:"mspace newline"}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6444em"}}),(0,a.jsx)(e.span,{className:"mord",children:"4"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4445em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]}),(0,a.jsx)(e.span,{className:"mspace newline"}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord",children:"5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4445em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]}),(0,a.jsx)(e.span,{className:"mspace newline"}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsxs)(e.span,{className:"mop",children:["lo",(0,a.jsx)(e.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,a.jsxs)(e.p,{children:["As you can see, this is worse than our ",(0,a.jsx)(e.em,{children:"greedy"})," solution that was incorrect, but\nit's better than the ",(0,a.jsx)(e.em,{children:"na\xefve"})," one."]}),"\n",(0,a.jsx)(e.h3,{id:"memory-complexity",children:"Memory complexity"}),"\n",(0,a.jsxs)(e.p,{children:["With this approach we need to talk about the memory complexity too, because we\nhave introduced cache. If you think that the memory complexity is linear to the\ninput, you are right. We start at the top and try to find each and every slide\ndown. At the end we get the final result for ",(0,a.jsx)(e.code,{children:"new Position(0, 0)"}),", so we need to\ncompute everything below."]}),"\n",(0,a.jsx)(e.p,{children:"That's how we obtain:"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(n)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsx)(e.mi,{children:"n"})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"n"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"})]})})]})," represents the total amount of cells in the pyramid, i.e."]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsxs)(e.munderover,{children:[(0,a.jsx)(e.mo,{children:"\u2211"}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"0"})]}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"p"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"y"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"r"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"a"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"m"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"i"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"d"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"."}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"l"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"e"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"n"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"g"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"t"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"h"})]}),(0,a.jsx)(e.mo,{children:"\u2212"}),(0,a.jsx)(e.mn,{children:"1"})]})]}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"p"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"y"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"r"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"a"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"m"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"i"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"d"})]}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mo,{fence:"true",children:"["}),(0,a.jsx)(e.mi,{children:"y"}),(0,a.jsx)(e.mo,{fence:"true",children:"]"})]}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"."}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"l"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"e"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"n"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"g"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"t"}),(0,a.jsx)(e.mi,{mathvariant:"monospace",children:"h"})]})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\sum_{y=0}^{\\mathtt{pyramid.length} - 1} \\mathtt{pyramid}\\left[y\\right]\\mathtt{.length}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"3.2709em",verticalAlign:"-1.4032em"}}),(0,a.jsx)(e.span,{className:"mop op-limits",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"1.8677em"},children:[(0,a.jsxs)(e.span,{style:{top:"-1.8829em",marginLeft:"0em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.05em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsxs)(e.span,{className:"mord mtight",children:[(0,a.jsx)(e.span,{className:"mord mathnormal mtight",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mrel mtight",children:"="}),(0,a.jsx)(e.span,{className:"mord mtight",children:"0"})]})})]}),(0,a.jsxs)(e.span,{style:{top:"-3.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.05em"}}),(0,a.jsx)(e.span,{children:(0,a.jsx)(e.span,{className:"mop op-symbol large-op",children:"\u2211"})})]}),(0,a.jsxs)(e.span,{style:{top:"-4.3666em",marginLeft:"0em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.05em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsxs)(e.span,{className:"mord mtight",children:[(0,a.jsx)(e.span,{className:"mord mtight",children:(0,a.jsx)(e.span,{className:"mord mathtt mtight",children:"pyramid.length"})}),(0,a.jsx)(e.span,{className:"mbin mtight",children:"\u2212"}),(0,a.jsx)(e.span,{className:"mord mtight",children:"1"})]})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"1.4032em"},children:(0,a.jsx)(e.span,{})})})]})}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathtt",children:"pyramid"})}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsxs)(e.span,{className:"minner",children:[(0,a.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:"["}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,a.jsx)(e.span,{className:"mclose delimcenter",style:{top:"0em"},children:"]"})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,a.jsx)(e.span,{className:"mord",children:(0,a.jsx)(e.span,{className:"mord mathtt",children:".length"})})]})})]})}),"\n",(0,a.jsx)(e.admonition,{type:"caution",children:(0,a.jsxs)(e.p,{children:["If you're wondering whether it's correct because of the second ",(0,a.jsx)(e.code,{children:"if"})," in our\nfunction, your guess is right. However we are expressing the complexity in the\nBachmann-Landau notation, so we care about the ",(0,a.jsx)(e.strong,{children:"upper bound"}),", not the exact\nnumber."]})}),"\n",(0,a.jsxs)(e.admonition,{title:"Can this be optimized?",type:"tip",children:[(0,a.jsx)(e.p,{children:"Yes, it can! Try to think about a way, how can you minimize the memory\ncomplexity of this approach. I'll give you a hint:"}),(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(rows)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})})]}),"\n",(0,a.jsx)(e.h2,{id:"bottom-up-dp",children:"Bottom-up DP"}),"\n",(0,a.jsxs)(e.p,{children:["If you try to think in depth about the top-down DP solution, you might notice\nthat the ",(0,a.jsx)(e.em,{children:"core"})," of it stands on caching the calculations that have been already\ndone on the lower \u201clevels\u201d of the pyramid. Our bottom-up implementation will be\nusing this fact!"]}),"\n",(0,a.jsxs)(e.admonition,{type:"tip",children:[(0,a.jsxs)(e.p,{children:["As I have said in the ",(0,a.jsx)(e.em,{children:"top-down DP"})," section, it is the easiest way to implement\nDP (unless the cached function has complicated parameters, in that case it might\nget messy)."]}),(0,a.jsx)(e.p,{children:"Bottom-up dynamic programming can be more effective, but may be more complicated\nto implement right from the beginning."})]}),"\n",(0,a.jsx)(e.p,{children:"Let's see how we can implement it:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-java",children:"public static int longestSlideDown(int[][] pyramid) {\n // In the beginning we declare new array. At this point it is easier to just\n // work with the one dimension, i.e. just allocating the space for the rows.\n int[][] slideDowns = new int[pyramid.length][];\n\n // Bottom row gets just copied, there's nothing else to do\u2026 It's the base\n // case.\n slideDowns[pyramid.length - 1] = Arrays.copyOf(pyramid[pyramid.length - 1],\n pyramid[pyramid.length - 1].length);\n\n // Then we need to propagate the found slide downs for each of the levels\n // above.\n for (int y = pyramid.length - 2; y >= 0; --y) {\n // We start by copying the values lying in the row we're processing.\n // They get included in the final sum and we need to allocate the space\n // for the precalculated slide downs anyways.\n int[] row = Arrays.copyOf(pyramid[y], pyramid[y].length);\n\n // At this we just need to \u201cfetch\u201d the partial results from \u201cneighbours\u201d\n for (int x = 0; x < row.length; ++x) {\n // We look under our position, since we expect the rows to get\n // shorter, we can safely assume such position exists.\n int under = slideDowns[y + 1][x];\n\n // Then we have a look to the right, such position doesn't have to\n // exist, e.g. on the right edge, so we validate the index, and if\n // it doesn't exist, we just assign minimum of the \u2039int\u203a which makes\n // sure that it doesn't get picked in the \u2039Math.max()\u203a call.\n int toRight = x + 1 < slideDowns[y + 1].length\n ? slideDowns[y + 1][x + 1]\n : Integer.MIN_VALUE;\n\n // Finally we add the best choice at this point.\n row[x] += Math.max(under, toRight);\n }\n\n // And save the row we've just calculated partial results for to the\n // \u201ctable\u201d.\n slideDowns[y] = row;\n }\n\n // At the end we can find our seeked slide down at the top cell.\n return slideDowns[0][0];\n}\n"})}),"\n",(0,a.jsx)(e.p,{children:"I've tried to explain the code as much as possible within the comments, since it\nmight be more beneficial to see right next to the \u201coffending\u201d lines."}),"\n",(0,a.jsxs)(e.p,{children:["As you can see, in this approach we go from the other side",(0,a.jsx)(e.sup,{children:(0,a.jsx)(e.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),", the bottom of\nthe pyramid and propagate the partial results up."]}),"\n",(0,a.jsxs)(e.admonition,{type:"info",children:[(0,a.jsxs)(e.mdxAdmonitionTitle,{children:["How is this different from the ",(0,a.jsx)(e.em,{children:"greedy"})," solution???"]}),(0,a.jsxs)(e.p,{children:["If you try to compare them, you might find a very noticable difference. The\ngreedy approach is going from the top to the bottom without ",(0,a.jsx)(e.strong,{children:"any"})," knowledge of\nwhat's going on below. On the other hand, bottom-up DP is going from the bottom\n(",(0,a.jsx)(e.em,{children:"DUH\u2026"}),") and ",(0,a.jsx)(e.strong,{children:"propagates"})," the partial results to the top. The propagation is\nwhat makes sure that at the top I don't choose the best ",(0,a.jsx)(e.strong,{children:"local"})," choice, but\nthe best ",(0,a.jsx)(e.strong,{children:"overall"})," result I can achieve."]})]}),"\n",(0,a.jsx)(e.h3,{id:"time-complexity-3",children:"Time complexity"}),"\n",(0,a.jsx)(e.p,{children:"Time complexity of this solution is rather simple. We allocate an array for the\nrows and then for each row, we copy it and adjust the partial results. Doing\nthis we get:"}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"r"}),(0,a.jsx)(e.mi,{children:"o"}),(0,a.jsx)(e.mi,{children:"w"}),(0,a.jsx)(e.mi,{children:"s"}),(0,a.jsx)(e.mo,{children:"+"}),(0,a.jsx)(e.mn,{children:"2"}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(rows + 2n)"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"+"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord",children:"2"}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,a.jsx)(e.p,{children:"Of course, this is an upper bound, since we iterate through the bottom row only\nonce."}),"\n",(0,a.jsx)(e.h3,{id:"memory-complexity-1",children:"Memory complexity"}),"\n",(0,a.jsxs)(e.p,{children:["We're allocating an array for the pyramid ",(0,a.jsx)(e.strong,{children:"again"})," for our partial results, so\nwe get:"]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{mathvariant:"script",children:"O"}),(0,a.jsx)(e.mo,{stretchy:"false",children:"("}),(0,a.jsx)(e.mi,{children:"n"}),(0,a.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(n)"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,a.jsx)(e.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(e.span,{className:"mopen",children:"("}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,a.jsx)(e.span,{className:"mclose",children:")"})]})})]})}),"\n",(0,a.jsxs)(e.admonition,{type:"tip",children:[(0,a.jsx)(e.p,{children:"If we were writing this in C++ or Rust, we could've avoided that, but not\nreally."}),(0,a.jsxs)(e.p,{children:["C++ would allow us to ",(0,a.jsx)(e.strong,{children:"copy"})," the pyramid rightaway into the parameter, so we\nwould be able to directly change it. However it's still a copy, even though we\ndon't need to allocate anything ourselves. It's just implicitly done for us."]}),(0,a.jsxs)(e.p,{children:["Rust is more funny in this case. If the pyramids weren't used after the call of\n",(0,a.jsx)(e.code,{children:"longest_slide_down"}),", it would simply ",(0,a.jsx)(e.strong,{children:"move"})," them into the functions. If they\nwere used afterwards, the compiler would force you to either borrow it, or\n",(0,a.jsx)(e.em,{children:"clone-and-move"})," for the function."]}),(0,a.jsx)(e.hr,{}),(0,a.jsxs)(e.p,{children:["Since we're doing it in Java, we get a reference to the ",(0,a.jsx)(e.em,{children:"original"})," array and we\ncan't do whatever we want with it."]})]}),"\n",(0,a.jsx)(e.h2,{id:"summary",children:"Summary"}),"\n",(0,a.jsxs)(e.p,{children:["And we've finally reached the end. We have seen 4 different \u201csolutions\u201d",(0,a.jsx)(e.sup,{children:(0,a.jsx)(e.a,{href:"#user-content-fn-4",id:"user-content-fnref-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"4"})})," of\nthe same problem using different approaches. Different approaches follow the\norder in which you might come up with them, each approach influences its\nsuccessor and represents the way we can enhance the existing implementation."]}),"\n",(0,a.jsx)(e.hr,{}),"\n",(0,a.jsx)(e.admonition,{title:"source",type:"info",children:(0,a.jsxs)(e.p,{children:["You can find source code referenced in the text\n",(0,a.jsx)(e.a,{href:"pathname:///files/algorithms/recursion/pyramid-slide-down.tar.gz",children:"here"}),"."]})}),"\n",(0,a.jsxs)(e.section,{"data-footnotes":!0,className:"footnotes",children:[(0,a.jsx)(e.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{id:"user-content-fn-1",children:["\n",(0,a.jsxs)(e.p,{children:["cause why not, right!? ",(0,a.jsx)(e.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(e.li,{id:"user-content-fn-2",children:["\n",(0,a.jsxs)(e.p,{children:["except the bottom row ",(0,a.jsx)(e.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(e.li,{id:"user-content-fn-3",children:["\n",(0,a.jsxs)(e.p,{children:["definitely not an RHCP reference ","\ud83d\ude09 ",(0,a.jsx)(e.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(e.li,{id:"user-content-fn-4",children:["\n",(0,a.jsxs)(e.p,{children:["one was not correct, thus the quotes ",(0,a.jsx)(e.a,{href:"#user-content-fnref-4","data-footnote-backref":"","aria-label":"Back to reference 4",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function o(s={}){const{wrapper:e}={...(0,i.a)(),...s.components};return e?(0,a.jsx)(e,{...s,children:(0,a.jsx)(h,{...s})}):h(s)}},11151:(s,e,n)=>{n.d(e,{Z:()=>r,a:()=>t});var a=n(67294);const i={},l=a.createContext(i);function t(s){const e=a.useContext(l);return a.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function r(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(i):s.components||i:t(s.components),a.createElement(l.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/7052c0bc.7402024f.js b/assets/js/7052c0bc.4005bc03.js similarity index 95% rename from assets/js/7052c0bc.7402024f.js rename to assets/js/7052c0bc.4005bc03.js index 0e18860..70768e2 100644 --- a/assets/js/7052c0bc.7402024f.js +++ b/assets/js/7052c0bc.4005bc03.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:1701199517,formattedLastUpdatedAt:"Nov 28, 2023",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:1701200735,formattedLastUpdatedAt:"Nov 28, 2023",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.166aea3d.js b/assets/js/794ef108.17b0c630.js similarity index 95% rename from assets/js/794ef108.166aea3d.js rename to assets/js/794ef108.17b0c630.js index de581e2..1fff41f 100644 --- a/assets/js/794ef108.166aea3d.js +++ b/assets/js/794ef108.17b0c630.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:1701199517,formattedLastUpdatedAt:"Nov 28, 2023",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:1701200735,formattedLastUpdatedAt:"Nov 28, 2023",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.7240ea58.js b/assets/js/84d1e0d8.a087077b.js similarity index 97% rename from assets/js/84d1e0d8.7240ea58.js rename to assets/js/84d1e0d8.a087077b.js index d064654..db5dc1e 100644 --- a/assets/js/84d1e0d8.7240ea58.js +++ b/assets/js/84d1e0d8.a087077b.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:1701199517,formattedLastUpdatedAt:"Nov 28, 2023",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:1701200735,formattedLastUpdatedAt:"Nov 28, 2023",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/aa24fd5d.143c547f.js b/assets/js/aa24fd5d.e4465696.js similarity index 58% rename from assets/js/aa24fd5d.143c547f.js rename to assets/js/aa24fd5d.e4465696.js index a0f600b..283b93f 100644 --- a/assets/js/aa24fd5d.143c547f.js +++ b/assets/js/aa24fd5d.e4465696.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[7257],{90251:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>h,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>o});var s=n(85893),i=n(11151);const r={id:"python",slug:"/hash-tables/breaking/python",title:"Breaking Python",description:"Actually getting the worst-case time complexity in Python.\n",tags:["cpp","python","hash-tables"],last_update:{date:new Date("2023-11-28T00:00:00.000Z")}},h="Breaking the Hash Table in Python",l={id:"hash-tables/2023-11-28-breaking/python",title:"Breaking Python",description:"Actually getting the worst-case time complexity in Python.\n",source:"@site/algorithms/12-hash-tables/2023-11-28-breaking/01-python.md",sourceDirName:"12-hash-tables/2023-11-28-breaking",slug:"/hash-tables/breaking/python",permalink:"/algorithms/hash-tables/breaking/python",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/12-hash-tables/2023-11-28-breaking/01-python.md",tags:[{label:"cpp",permalink:"/algorithms/tags/cpp"},{label:"python",permalink:"/algorithms/tags/python"},{label:"hash-tables",permalink:"/algorithms/tags/hash-tables"}],version:"current",lastUpdatedAt:1701129600,formattedLastUpdatedAt:"Nov 28, 2023",sidebarPosition:1,frontMatter:{id:"python",slug:"/hash-tables/breaking/python",title:"Breaking Python",description:"Actually getting the worst-case time complexity in Python.\n",tags:["cpp","python","hash-tables"],last_update:{date:"2023-11-28T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Breaking Hash Table",permalink:"/algorithms/hash-tables/breaking"},next:{title:"Possible Mitigations",permalink:"/algorithms/hash-tables/breaking/mitigations"}},a={},o=[{value:"Preparing the attack",id:"preparing-the-attack",level:2},{value:"Sequences",id:"sequences",level:3},{value:"Results",id:"results",level:2},{value:"Comparing with the tree",id:"comparing-with-the-tree",level:2},{value:"References",id:"references",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",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)(t.h1,{id:"breaking-the-hash-table-in-python",children:"Breaking the Hash Table in Python"}),"\n",(0,s.jsxs)(t.p,{children:["Our language of choice for bringing the worst out of the hash table is ",(0,s.jsx)(t.em,{children:"Python"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["Let's start by talking about the hash function and why we've chosen Python for\nthis. Hash function for integers in Python is simply ",(0,s.jsx)(t.em,{children:"identity"}),", as you might've\nguessed, there's no avalanche effect. Another thing that helps us is the fact\nthat integers in Python are technically ",(0,s.jsx)(t.code,{children:"BigInt"}),"s",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),". This allows us to put bit\nmore pressure on the hashing function."]}),"\n",(0,s.jsxs)(t.p,{children:["From the perspective of the implementation, it is a hash table that uses probing\nto resolve conflicts. This also means that it's a contiguous space in memory.\nIndexing works like in the provided example above. When the hash table reaches\na ",(0,s.jsx)(t.em,{children:"breaking point"})," (defined somewhere in the C code), it reallocates the table\nand rehashes everything."]}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsx)(t.p,{children:"Resizing and rehashing can reduce the conflicts. That is coming from the fact\nthat the position in the table is determined by the hash and the size of the\ntable itself."})}),"\n",(0,s.jsx)(t.h2,{id:"preparing-the-attack",children:"Preparing the attack"}),"\n",(0,s.jsx)(t.p,{children:"Knowing the things above, it is not that hard to construct a method how to cause\nas many conflicts as possible. Let's go over it:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"We know that integers are hashed to themselves."}),"\n",(0,s.jsx)(t.li,{children:"We also know that from that hash we use only lower bits that are used as\nindices."}),"\n",(0,s.jsx)(t.li,{children:"We also know that there's a rehashing on resize that could possibly fix the\nconflicts."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"We will test with different sequences:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"ordered one, numbers through 1 to N"}),"\n",(0,s.jsx)(t.li,{children:"ordered one in a reversed order, numbers through N back to 1"}),"\n",(0,s.jsx)(t.li,{children:"numbers that are shifted to the left, so they create conflicts until resize"}),"\n",(0,s.jsx)(t.li,{children:"numbers that are shifted to the left, but resizing helps only in the end"}),"\n",(0,s.jsx)(t.li,{children:"numbers that are shifted to the left, but they won't be taken in account even\nafter final resize"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"For each of these sequences, we will insert 10\u2077 elements and look each of them\nup for 10 times in a row."}),"\n",(0,s.jsxs)(t.p,{children:["As a base of our benchmark, we will use a ",(0,s.jsx)(t.code,{children:"Strategy"})," class and then for each\nstrategy we will just implement the sequence of numbers that it uses:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:'class Strategy:\n def __init__(self, data_structure=set):\n self._table = data_structure()\n\n @cached_property\n def elements(self):\n raise NotImplementedError("Implement for each strategy")\n\n @property\n def name(self):\n raise NotImplementedError("Implement for each strategy")\n\n def run(self):\n print(f"\\nBenchmarking:\\t\\t{self.name}")\n\n # Extract the elements here, so that the evaluation of them does not\n # slow down the relevant part of benchmark\n elements = self.elements\n\n # Insertion phase\n start = monotonic_ns()\n for x in elements:\n self._table.add(x)\n after_insertion = monotonic_ns()\n\n print(f"Insertion phase:\\t{(after_insertion - start) / 1000000:.2f}ms")\n\n # Lookup phase\n start = monotonic_ns()\n for _ in range(LOOPS):\n for x in elements:\n assert x in self._table\n after_lookups = monotonic_ns()\n\n print(f"Lookup phase:\\t\\t{(after_lookups - start) / 1000000:.2f}ms")\n'})}),"\n",(0,s.jsx)(t.h3,{id:"sequences",children:"Sequences"}),"\n",(0,s.jsx)(t.p,{children:"Let's have a look at how we generate the numbers to be inserted:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["ordered sequence (ascending)","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"x for x in range(N_ELEMENTS)\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["ordered sequence (descending)","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"x for x in reversed(range(N_ELEMENTS))\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["progressive sequence that \u201cheals\u201d on resize","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"(x << max(5, x.bit_length())) for x in range(N_ELEMENTS)\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["progressive sequence that \u201cheals\u201d in the end","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"(x << max(5, x.bit_length())) for x in reversed(range(N_ELEMENTS))\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["conflicts everywhere","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"x << 32 for x in range(N_ELEMENTS)\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"results",children:"Results"}),"\n",(0,s.jsx)(t.p,{children:"Let's have a look at the obtained results after running the code:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Technique"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Insertion phase"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Lookup phase"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"ordered sequence (ascending)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"558.60ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"3304.26ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"ordered sequence (descending)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"554.08ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"3365.84ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"progressive sequence that \u201cheals\u201d on resize"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"3781.30ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"28565.71ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"progressive sequence that \u201cheals\u201d in the end"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"3280.38ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"26494.61ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"conflicts everywhere"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"4027.54ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"29132.92ms"})})]})]})]}),"\n",(0,s.jsx)(t.p,{children:"You can see a noticable \u201cjump\u201d in the time after switching to the \u201cprogressive\u201d\nsequence. The last sequence that has conflicts all the time has the worst time,\neven though it's rather comparable with the first progressive sequence with\nregards to the insertion phase."}),"\n",(0,s.jsxs)(t.p,{children:["If we were to compare the ",(0,s.jsx)(t.em,{children:"always conflicting"})," one with the first one, we can\nsee that insertion took over 7\xd7 longer and lookups almost 9\xd7 longer."]}),"\n",(0,s.jsxs)(t.p,{children:["You can have a look at the code ",(0,s.jsx)(t.a,{href:"path:///files/algorithms/hash-tables/breaking/benchmark.py",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"comparing-with-the-tree",children:"Comparing with the tree"}),"\n",(0,s.jsxs)(t.admonition,{type:"danger",children:[(0,s.jsxs)(t.p,{children:["Source code can be found ",(0,s.jsx)(t.a,{href:"path:///files/algorithms/hash-tables/breaking/benchmark.cpp",children:"here"}),"."]}),(0,s.jsx)(t.p,{children:(0,s.jsx)(t.em,{children:"Viewer discretion advised."})})]}),"\n",(0,s.jsx)(t.p,{children:"Python doesn't have a tree structure for sets/maps implemented, therefore for\na comparison we will run a similar benchmark in C++. By running the same\nsequences on both hash table and tree (RB-tree) we will obtain the following\nresults:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Technique"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Insertion (hash)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Lookup (hash)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Insertion (tree)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Lookup (tree)"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"ordered (ascending)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"316ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"298ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"2098ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"5914ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"ordered (descending)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"259ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"315ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"1958ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"14747ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"progressive a)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"1152ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"6021ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"2581ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"16074ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"progressive b)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"1041ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"6096ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"2770ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"15986ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"conflicts"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"964ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"1633ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"2559ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"13285ms"})})]})]})]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"We can't forget that implementation details be involved. Hash function is still\nthe identity, to my knowledge."})}),"\n",(0,s.jsx)(t.p,{children:"One interesting thing to notice is the fact that the progressive sequences took\nthe most time in lookups (which is not same as in the Python)."}),"\n",(0,s.jsx)(t.p,{children:"Now, if we have a look at the tree implementation, we can notice two very\ndistinctive things:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Tree implementations are not affected by the input, therefore (except for the\nfirst sequence) we can see ",(0,s.jsx)(t.strong,{children:"very consistent"})," times."]}),"\n",(0,s.jsx)(t.li,{children:"Compared to the hash table the times are much higher and not very ideal."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The reason for the 2nd point may not be very obvious. From the technical\nperspective it makes some sense. Let's dive into it!"}),"\n",(0,s.jsxs)(t.p,{children:["If we take a hash table, it is an array in a memory, therefore it is contiguous\npiece of memory. (For more information I'd suggest looking into the 1st blog\npost below in references section by ",(0,s.jsx)(t.em,{children:"Bjarne Stroustrup"}),")"]}),"\n",(0,s.jsxs)(t.p,{children:["On the other hand, if we take a look at the tree, each node holds some\nattributes and pointers to the left and right descendants of itself. Even if we\nmaintain a reasonable height of the tree (keep the tree balanced), we still need\nto follow the pointers which point to the nodes ",(0,s.jsx)(t.em,{children:"somewhere"})," on the heap. When\ntraversing the tree, we get a consistent time complexity, but at the expense of\njumping between the nodes on the heap which takes some time."]}),"\n",(0,s.jsxs)(t.admonition,{type:"danger",children:[(0,s.jsx)(t.p,{children:"This is not supposed to leverage the hash table and try to persuade people not\nto use the tree representations. There are benefits coming from the respective\ndata structures, even if the time is not the best."}),(0,s.jsx)(t.p,{children:"Overall if we compare the worst-case time complexities of the tree and hash\ntable, tree representation comes off better."})]}),"\n",(0,s.jsx)(t.admonition,{title:"Challenge",type:"tip",children:(0,s.jsx)(t.p,{children:"Try to benchmark with the similar approach in the Rust. Since Rust uses\ndifferent hash function, it would be the best to just override the hash, this\nway you can also avoid the hard part of this attack (making up the numbers that\nwill collide)."})}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h2,{id:"references",children:"References"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Bjarne Stroustrup.\n",(0,s.jsx)(t.a,{href:"https://www.stroustrup.com/bs_faq.html#list",children:"Are lists evil?"})]}),"\n"]}),"\n",(0,s.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(t.p,{children:["Arbitrary-sized integers, they can get as big as your memory allows. ",(0,s.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},11151:(e,t,n)=>{n.d(t,{Z:()=>l,a:()=>h});var s=n(67294);const i={},r=s.createContext(i);function h(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:h(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[7257],{90251:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>h,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>o});var s=n(85893),i=n(11151);const r={id:"python",slug:"/hash-tables/breaking/python",title:"Breaking Python",description:"Actually getting the worst-case time complexity in Python.\n",tags:["cpp","python","hash-tables"],last_update:{date:new Date("2023-11-28T00:00:00.000Z")}},h="Breaking the Hash Table in Python",l={id:"hash-tables/2023-11-28-breaking/python",title:"Breaking Python",description:"Actually getting the worst-case time complexity in Python.\n",source:"@site/algorithms/12-hash-tables/2023-11-28-breaking/01-python.md",sourceDirName:"12-hash-tables/2023-11-28-breaking",slug:"/hash-tables/breaking/python",permalink:"/algorithms/hash-tables/breaking/python",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/12-hash-tables/2023-11-28-breaking/01-python.md",tags:[{label:"cpp",permalink:"/algorithms/tags/cpp"},{label:"python",permalink:"/algorithms/tags/python"},{label:"hash-tables",permalink:"/algorithms/tags/hash-tables"}],version:"current",lastUpdatedAt:1701129600,formattedLastUpdatedAt:"Nov 28, 2023",sidebarPosition:1,frontMatter:{id:"python",slug:"/hash-tables/breaking/python",title:"Breaking Python",description:"Actually getting the worst-case time complexity in Python.\n",tags:["cpp","python","hash-tables"],last_update:{date:"2023-11-28T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Breaking Hash Table",permalink:"/algorithms/hash-tables/breaking"},next:{title:"Possible Mitigations",permalink:"/algorithms/hash-tables/breaking/mitigations"}},a={},o=[{value:"Preparing the attack",id:"preparing-the-attack",level:2},{value:"Sequences",id:"sequences",level:3},{value:"Results",id:"results",level:2},{value:"Comparing with the tree",id:"comparing-with-the-tree",level:2},{value:"References",id:"references",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",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)(t.h1,{id:"breaking-the-hash-table-in-python",children:"Breaking the Hash Table in Python"}),"\n",(0,s.jsxs)(t.p,{children:["Our language of choice for bringing the worst out of the hash table is ",(0,s.jsx)(t.em,{children:"Python"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["Let's start by talking about the hash function and why we've chosen Python for\nthis. Hash function for integers in Python is simply ",(0,s.jsx)(t.em,{children:"identity"}),", as you might've\nguessed, there's no avalanche effect. Another thing that helps us is the fact\nthat integers in Python are technically ",(0,s.jsx)(t.code,{children:"BigInt"}),"s",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),". This allows us to put bit\nmore pressure on the hashing function."]}),"\n",(0,s.jsxs)(t.p,{children:["From the perspective of the implementation, it is a hash table that uses probing\nto resolve conflicts. This also means that it's a contiguous space in memory.\nIndexing works like in the provided example above. When the hash table reaches\na ",(0,s.jsx)(t.em,{children:"breaking point"})," (defined somewhere in the C code), it reallocates the table\nand rehashes everything."]}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsx)(t.p,{children:"Resizing and rehashing can reduce the conflicts. That is coming from the fact\nthat the position in the table is determined by the hash and the size of the\ntable itself."})}),"\n",(0,s.jsx)(t.h2,{id:"preparing-the-attack",children:"Preparing the attack"}),"\n",(0,s.jsx)(t.p,{children:"Knowing the things above, it is not that hard to construct a method how to cause\nas many conflicts as possible. Let's go over it:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"We know that integers are hashed to themselves."}),"\n",(0,s.jsx)(t.li,{children:"We also know that from that hash we use only lower bits that are used as\nindices."}),"\n",(0,s.jsx)(t.li,{children:"We also know that there's a rehashing on resize that could possibly fix the\nconflicts."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"We will test with different sequences:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"ordered one, numbers through 1 to N"}),"\n",(0,s.jsx)(t.li,{children:"ordered one in a reversed order, numbers through N back to 1"}),"\n",(0,s.jsx)(t.li,{children:"numbers that are shifted to the left, so they create conflicts until resize"}),"\n",(0,s.jsx)(t.li,{children:"numbers that are shifted to the left, but resizing helps only in the end"}),"\n",(0,s.jsx)(t.li,{children:"numbers that are shifted to the left, but they won't be taken in account even\nafter final resize"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"For each of these sequences, we will insert 10\u2077 elements and look each of them\nup for 10 times in a row."}),"\n",(0,s.jsxs)(t.p,{children:["As a base of our benchmark, we will use a ",(0,s.jsx)(t.code,{children:"Strategy"})," class and then for each\nstrategy we will just implement the sequence of numbers that it uses:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:'class Strategy:\n def __init__(self, data_structure=set):\n self._table = data_structure()\n\n @cached_property\n def elements(self):\n raise NotImplementedError("Implement for each strategy")\n\n @property\n def name(self):\n raise NotImplementedError("Implement for each strategy")\n\n def run(self):\n print(f"\\nBenchmarking:\\t\\t{self.name}")\n\n # Extract the elements here, so that the evaluation of them does not\n # slow down the relevant part of benchmark\n elements = self.elements\n\n # Insertion phase\n start = monotonic_ns()\n for x in elements:\n self._table.add(x)\n after_insertion = monotonic_ns()\n\n print(f"Insertion phase:\\t{(after_insertion - start) / 1000000:.2f}ms")\n\n # Lookup phase\n start = monotonic_ns()\n for _ in range(LOOPS):\n for x in elements:\n assert x in self._table\n after_lookups = monotonic_ns()\n\n print(f"Lookup phase:\\t\\t{(after_lookups - start) / 1000000:.2f}ms")\n'})}),"\n",(0,s.jsx)(t.h3,{id:"sequences",children:"Sequences"}),"\n",(0,s.jsx)(t.p,{children:"Let's have a look at how we generate the numbers to be inserted:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["ordered sequence (ascending)","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"x for x in range(N_ELEMENTS)\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["ordered sequence (descending)","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"x for x in reversed(range(N_ELEMENTS))\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["progressive sequence that \u201cheals\u201d on resize","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"(x << max(5, x.bit_length())) for x in range(N_ELEMENTS)\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["progressive sequence that \u201cheals\u201d in the end","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"(x << max(5, x.bit_length())) for x in reversed(range(N_ELEMENTS))\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["conflicts everywhere","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-py",children:"x << 32 for x in range(N_ELEMENTS)\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"results",children:"Results"}),"\n",(0,s.jsx)(t.p,{children:"Let's have a look at the obtained results after running the code:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Technique"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Insertion phase"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Lookup phase"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"ordered sequence (ascending)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"558.60ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"3304.26ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"ordered sequence (descending)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"554.08ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"3365.84ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"progressive sequence that \u201cheals\u201d on resize"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"3781.30ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"28565.71ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"progressive sequence that \u201cheals\u201d in the end"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"3280.38ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"26494.61ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"conflicts everywhere"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"4027.54ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"29132.92ms"})})]})]})]}),"\n",(0,s.jsx)(t.p,{children:"You can see a noticable \u201cjump\u201d in the time after switching to the \u201cprogressive\u201d\nsequence. The last sequence that has conflicts all the time has the worst time,\neven though it's rather comparable with the first progressive sequence with\nregards to the insertion phase."}),"\n",(0,s.jsxs)(t.p,{children:["If we were to compare the ",(0,s.jsx)(t.em,{children:"always conflicting"})," one with the first one, we can\nsee that insertion took over 7\xd7 longer and lookups almost 9\xd7 longer."]}),"\n",(0,s.jsxs)(t.p,{children:["You can have a look at the code ",(0,s.jsx)(t.a,{href:"pathname:///files/algorithms/hash-tables/breaking/benchmark.py",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"comparing-with-the-tree",children:"Comparing with the tree"}),"\n",(0,s.jsxs)(t.admonition,{type:"danger",children:[(0,s.jsxs)(t.p,{children:["Source code can be found ",(0,s.jsx)(t.a,{href:"pathname:///files/algorithms/hash-tables/breaking/benchmark.cpp",children:"here"}),"."]}),(0,s.jsx)(t.p,{children:(0,s.jsx)(t.em,{children:"Viewer discretion advised."})})]}),"\n",(0,s.jsx)(t.p,{children:"Python doesn't have a tree structure for sets/maps implemented, therefore for\na comparison we will run a similar benchmark in C++. By running the same\nsequences on both hash table and tree (RB-tree) we will obtain the following\nresults:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Technique"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Insertion (hash)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Lookup (hash)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Insertion (tree)"}),(0,s.jsx)(t.th,{style:{textAlign:"right"},children:"Lookup (tree)"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"ordered (ascending)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"316ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"298ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"2098ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"5914ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"ordered (descending)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"259ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"315ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"1958ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"14747ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"progressive a)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"1152ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"6021ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"2581ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"16074ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"progressive b)"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"1041ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"6096ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"2770ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"15986ms"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"conflicts"}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"964ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"1633ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"2559ms"})}),(0,s.jsx)(t.td,{style:{textAlign:"right"},children:(0,s.jsx)(t.code,{children:"13285ms"})})]})]})]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"We can't forget that implementation details be involved. Hash function is still\nthe identity, to my knowledge."})}),"\n",(0,s.jsx)(t.p,{children:"One interesting thing to notice is the fact that the progressive sequences took\nthe most time in lookups (which is not same as in the Python)."}),"\n",(0,s.jsx)(t.p,{children:"Now, if we have a look at the tree implementation, we can notice two very\ndistinctive things:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Tree implementations are not affected by the input, therefore (except for the\nfirst sequence) we can see ",(0,s.jsx)(t.strong,{children:"very consistent"})," times."]}),"\n",(0,s.jsx)(t.li,{children:"Compared to the hash table the times are much higher and not very ideal."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The reason for the 2nd point may not be very obvious. From the technical\nperspective it makes some sense. Let's dive into it!"}),"\n",(0,s.jsxs)(t.p,{children:["If we take a hash table, it is an array in a memory, therefore it is contiguous\npiece of memory. (For more information I'd suggest looking into the 1st blog\npost below in references section by ",(0,s.jsx)(t.em,{children:"Bjarne Stroustrup"}),")"]}),"\n",(0,s.jsxs)(t.p,{children:["On the other hand, if we take a look at the tree, each node holds some\nattributes and pointers to the left and right descendants of itself. Even if we\nmaintain a reasonable height of the tree (keep the tree balanced), we still need\nto follow the pointers which point to the nodes ",(0,s.jsx)(t.em,{children:"somewhere"})," on the heap. When\ntraversing the tree, we get a consistent time complexity, but at the expense of\njumping between the nodes on the heap which takes some time."]}),"\n",(0,s.jsxs)(t.admonition,{type:"danger",children:[(0,s.jsx)(t.p,{children:"This is not supposed to leverage the hash table and try to persuade people not\nto use the tree representations. There are benefits coming from the respective\ndata structures, even if the time is not the best."}),(0,s.jsx)(t.p,{children:"Overall if we compare the worst-case time complexities of the tree and hash\ntable, tree representation comes off better."})]}),"\n",(0,s.jsx)(t.admonition,{title:"Challenge",type:"tip",children:(0,s.jsx)(t.p,{children:"Try to benchmark with the similar approach in the Rust. Since Rust uses\ndifferent hash function, it would be the best to just override the hash, this\nway you can also avoid the hard part of this attack (making up the numbers that\nwill collide)."})}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h2,{id:"references",children:"References"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Bjarne Stroustrup.\n",(0,s.jsx)(t.a,{href:"https://www.stroustrup.com/bs_faq.html#list",children:"Are lists evil?"})]}),"\n"]}),"\n",(0,s.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(t.p,{children:["Arbitrary-sized integers, they can get as big as your memory allows. ",(0,s.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},11151:(e,t,n)=>{n.d(t,{Z:()=>l,a:()=>h});var s=n(67294);const i={},r=s.createContext(i);function h(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:h(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1288602.2548704d.js b/assets/js/b1288602.70376235.js similarity index 98% rename from assets/js/b1288602.2548704d.js rename to assets/js/b1288602.70376235.js index f51aaf9..6291fce 100644 --- a/assets/js/b1288602.2548704d.js +++ b/assets/js/b1288602.70376235.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:1701199517,formattedLastUpdatedAt:"Nov 28, 2023",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:1701200735,formattedLastUpdatedAt:"Nov 28, 2023",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.ac17e06f.js b/assets/js/d05e838c.f0798c93.js similarity index 99% rename from assets/js/d05e838c.ac17e06f.js rename to assets/js/d05e838c.f0798c93.js index 178267b..4e8262e 100644 --- a/assets/js/d05e838c.ac17e06f.js +++ b/assets/js/d05e838c.f0798c93.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:1701199517,formattedLastUpdatedAt:"Nov 28, 2023",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:1701200735,formattedLastUpdatedAt:"Nov 28, 2023",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.a809bb25.js b/assets/js/main.9ec99e33.js similarity index 99% rename from assets/js/main.a809bb25.js rename to assets/js/main.9ec99e33.js index f5f99de..9f90bb9 100644 --- a/assets/js/main.a809bb25.js +++ b/assets/js/main.9ec99e33.js @@ -1,2 +1,2 @@ -/*! For license information please see main.a809bb25.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],"087808f1":[()=>n.e(3731).then(n.bind(n,48157)),"@site/algorithms/12-hash-tables/2023-11-28-breaking/index.md",48157],"0bfe45d5":[()=>n.e(4269).then(n.t.bind(n,13847,19)),"~blog/blog/blog-tags-rust-0c9-list.json",13847],"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],17896441:[()=>Promise.all([n.e(532),n.e(1325),n.e(7918)]).then(n.bind(n,15154)),"@theme/DocItem",15154],"19d7c045":[()=>n.e(4637).then(n.t.bind(n,67772,19)),"~blog/blog/blog-tags-advent-of-code-49f.json",67772],"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],"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],"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],"2b89902a":[()=>n.e(6342).then(n.t.bind(n,45443,19)),"~docs/algorithms/tag-algorithms-tags-recursion-1bd.json",45443],"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],"34ab65f4":[()=>n.e(3220).then(n.t.bind(n,28865,19)),"~docs/algorithms/tag-algorithms-tags-postconditions-1f3.json",28865],"354a7b72":[()=>n.e(9414).then(n.bind(n,46617)),"@site/algorithms/10-graphs/2022-04-30-bfs-tree.md",46617],"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],"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],"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],51624505:[()=>n.e(4394).then(n.bind(n,32609)),"@site/blog/aoc-2022/00-intro.md",32609],"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],"595c7293":[()=>n.e(5634).then(n.bind(n,58396)),"@site/c/bonuses/08.md",58396],"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],"5e95c892":[()=>n.e(9661).then(n.bind(n,41892)),"@theme/DocsRoot",41892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,36809)),"@generated/docusaurus.config",36809],"5fe5d476":[()=>n.e(2619).then(n.bind(n,14457)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down.md",14457],"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],"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],"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],"794ef108":[()=>n.e(3803).then(n.bind(n,86427)),"@site/c/00-intro.md",86427],"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],"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],"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],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],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],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],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],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],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],d1aceb2e:[()=>n.e(1353).then(n.bind(n,71466)),"@site/algorithms/04-recursion/2022-11-29-karel-1.md",71466],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],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],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],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],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],f48be158:[()=>n.e(4064).then(n.bind(n,12326)),"@site/blog/aoc-2022/03-week-3.md",12326],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/","608"),exact:!0},{path:"/blog/2023/08/02/copr/",component:d("/blog/2023/08/02/copr/","69d"),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/tags/",component:d("/blog/tags/","f23"),exact:!0},{path:"/blog/tags/\ud83c\udfed/",component:d("/blog/tags/\ud83c\udfed/","ffd"),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/copr/",component:d("/blog/tags/copr/","959"),exact:!0},{path:"/blog/tags/cpp/",component:d("/blog/tags/cpp/","770"),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/red-hat/",component:d("/blog/tags/red-hat/","a58"),exact:!0},{path:"/blog/tags/rust/",component:d("/blog/tags/rust/","281"),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/","f04"),routes:[{path:"/algorithms/",component:d("/algorithms/","d58"),routes:[{path:"/algorithms/tags/",component:d("/algorithms/tags/","bb8"),exact:!0},{path:"/algorithms/tags/applications/",component:d("/algorithms/tags/applications/","b32"),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/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/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/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/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/","301"),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/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/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-1/",component:d("/algorithms/recursion/karel-1/","600"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/",component:d("/algorithms/recursion/pyramid-slide-down/","947"),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(7439),n(57800)];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 N=n(98934),j=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":{"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},"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":"rb-trees/applications","path":"/algorithms/rb-trees/applications","sidebar":"autogeneratedBar"},{"id":"rb-trees/rules","path":"/algorithms/rb-trees/rules","sidebar":"autogeneratedBar"},{"id":"recursion/karel-1","path":"/algorithms/recursion/karel-1","sidebar":"autogeneratedBar"},{"id":"recursion/pyramid-slide-down","path":"/algorithms/recursion/pyramid-slide-down","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/hash-tables","path":"/algorithms/category/hash-tables","sidebar":"autogeneratedBar"}],"draftIds":[],"sidebars":{"autogeneratedBar":{"link":{"path":"/algorithms/","label":"algorithms-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 N=(0,r.useRef)(!1),j=n?a.OL:a.rU,L=l.Z.canUseIntersectionObserver,P=(0,r.useRef)(),R=()=>{N.current||null==T||(window.docusaurus.preload(T),N.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)(j,{...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 N=n(93163),j=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,N.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,N.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 Ne=n(73935);const je={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:je.button}),b&&Le&&h.current&&(0,Ne.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:je.placeholder,translations:je.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,N.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,N.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,N.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,j.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,N.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,N.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,j.OC,ze.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(P.n2,{children:(0,u.jsx)(N.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)},57800:(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]),N=r(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[A]),2),j=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,L=t(/<<0>>(?:\s*\(<<1>>*\))?/.source,[b,N]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:n(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[j,L]),lookbehind:!0,greedy:!0,inside:{target:{pattern:n(/^<<0>>(?=\s*:)/.source,[j]),alias:"keyword"},"attribute-arguments":{pattern:n(/\(<<0>>*\)/.source,[N]),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