From 34eebcc6d0be65749580a688b6b00d00132ce3f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 4 Feb 2024 12:54:29 +0000 Subject: [PATCH] deploy: 3f87535d86423d7dc57dbe572c76028a0f44805f --- 404.html | 4 +- .../postcondition-ambiguity/index.html | 22 +- .../algorithms-and-correctness/index.html | 4 +- .../index.html | 4 +- algorithms/category/graphs/index.html | 4 +- algorithms/category/hash-tables/index.html | 4 +- .../category/paths-in-graphs/index.html | 4 +- algorithms/category/recursion/index.html | 4 +- .../category/red-black-trees/index.html | 4 +- algorithms/graphs/bfs-tree/index.html | 4 +- .../graphs/iterative-and-iterators/index.html | 12 +- algorithms/hash-tables/breaking/index.html | 10 +- .../breaking/mitigations/index.html | 16 +- .../hash-tables/breaking/python/index.html | 16 +- algorithms/index.html | 6 +- algorithms/paths/bf-to-astar/astar/index.html | 12 +- algorithms/paths/bf-to-astar/bf/index.html | 24 +- .../paths/bf-to-astar/dijkstra/index.html | 14 +- algorithms/paths/bf-to-astar/index.html | 10 +- algorithms/rb-trees/applications/index.html | 28 +-- algorithms/rb-trees/rules/index.html | 6 +- algorithms/recursion/karel/index.html | 6 +- .../recursion/karel/solution/index.html | 22 +- .../bottom-up-dp/index.html | 6 +- .../pyramid-slide-down/greedy/index.html | 10 +- .../recursion/pyramid-slide-down/index.html | 12 +- .../pyramid-slide-down/naive/index.html | 12 +- .../pyramid-slide-down/top-down-dp/index.html | 8 +- algorithms/tags/a-star/index.html | 4 +- algorithms/tags/applications/index.html | 4 +- algorithms/tags/astar/index.html | 4 +- algorithms/tags/backtracking/index.html | 4 +- algorithms/tags/balanced-trees/index.html | 4 +- algorithms/tags/bellman-ford/index.html | 4 +- algorithms/tags/bfs/index.html | 4 +- algorithms/tags/bottom-up-dp/index.html | 4 +- algorithms/tags/brute-force/index.html | 4 +- algorithms/tags/c/index.html | 4 +- algorithms/tags/cpp/index.html | 4 +- algorithms/tags/csharp/index.html | 4 +- algorithms/tags/dijkstra/index.html | 4 +- algorithms/tags/dynamic-array/index.html | 4 +- .../tags/dynamic-programming/index.html | 4 +- algorithms/tags/exponential/index.html | 4 +- algorithms/tags/graphs/index.html | 4 +- algorithms/tags/greedy/index.html | 4 +- algorithms/tags/hash-tables/index.html | 4 +- algorithms/tags/index.html | 4 +- algorithms/tags/iterative/index.html | 4 +- algorithms/tags/iterators/index.html | 4 +- algorithms/tags/java/index.html | 4 +- algorithms/tags/karel/index.html | 4 +- algorithms/tags/postconditions/index.html | 4 +- algorithms/tags/python/index.html | 4 +- algorithms/tags/recursion/index.html | 4 +- algorithms/tags/red-black-trees/index.html | 4 +- algorithms/tags/solution/index.html | 4 +- algorithms/tags/sorting/index.html | 4 +- algorithms/tags/testing/index.html | 4 +- algorithms/tags/time-complexity/index.html | 4 +- algorithms/tags/top-down-dp/index.html | 4 +- algorithms/time-complexity/extend/index.html | 8 +- assets/js/1535ede8.b272bba2.js | 1 + assets/js/1535ede8.cf110382.js | 1 - assets/js/595c7293.8b475e77.js | 1 + assets/js/595c7293.e8aa1f47.js | 1 - assets/js/7052c0bc.61d77968.js | 1 - assets/js/7052c0bc.cf9e5f57.js | 1 + assets/js/794ef108.083736fa.js | 1 + assets/js/794ef108.8d36eaa9.js | 1 - assets/js/84d1e0d8.478c5852.js | 1 + assets/js/84d1e0d8.f337d099.js | 1 - assets/js/b1288602.19054c2d.js | 1 - assets/js/b1288602.9aa1a8e6.js | 1 + assets/js/d05e838c.0813f6b5.js | 1 + assets/js/d05e838c.642ce149.js | 1 - .../js/{main.5d53fbfc.js => main.237fcc8a.js} | 4 +- ...CENSE.txt => main.237fcc8a.js.LICENSE.txt} | 0 ...n.55537369.js => runtime~main.f2ae61cf.js} | 2 +- blog/2023/08/02/copr/index.html | 6 +- blog/2024/01/28/rust-opinion/index.html | 22 +- blog/aoc-2022/1st-week/index.html | 42 ++-- blog/aoc-2022/2nd-week/index.html | 62 ++--- blog/aoc-2022/3rd-week/index.html | 22 +- blog/aoc-2022/4th-week/index.html | 42 ++-- blog/aoc-2022/intro/index.html | 28 +-- blog/archive/index.html | 4 +- blog/atom.xml | 228 +++++++++--------- blog/feed.json | 16 +- blog/index.html | 4 +- blog/leetcode/sort-diagonally/index.html | 38 +-- blog/rss.xml | 228 +++++++++--------- 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/cult/index.html | 4 +- blog/tags/hype/index.html | 4 +- blog/tags/index.html | 4 +- blog/tags/iterators/index.html | 4 +- blog/tags/leetcode/index.html | 4 +- blog/tags/memory-safety/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 | 8 +- c/bonuses/seminar-04/index.html | 20 +- c/bonuses/seminar-05-06/index.html | 14 +- c/bonuses/seminar-08/index.html | 12 +- c/bonuses/seminar-10/index.html | 14 +- c/category/bonuses/index.html | 4 +- c/category/practice-exams/index.html | 4 +- c/index.html | 6 +- c/mr/index.html | 16 +- c/pexam/cams/index.html | 8 +- c/pexam/garbage_collect/index.html | 8 +- contributions/index.html | 4 +- cpp/category/exceptions-and-raii/index.html | 4 +- cpp/environment/index.html | 10 +- .../placeholders/index.html | 22 +- cpp/index.html | 6 +- .../graphs/iterative-and-iterators.tar.bz2 | Bin 1934 -> 1934 bytes .../graphs/iterative-and-iterators.tar.gz | Bin 1943 -> 1960 bytes files/algorithms/paths/bf-to-astar.tar.bz2 | Bin 3166 -> 3166 bytes files/algorithms/paths/bf-to-astar.tar.gz | Bin 2994 -> 2992 bytes files/algorithms/recursion/karel-1.tar.bz2 | Bin 5882 -> 5871 bytes files/algorithms/recursion/karel-1.tar.gz | Bin 6583 -> 6581 bytes .../recursion/pyramid-slide-down.tar.bz2 | Bin 1548 -> 1547 bytes .../recursion/pyramid-slide-down.tar.gz | Bin 1423 -> 1421 bytes .../algorithms/time-complexity/extend.tar.bz2 | Bin 4069 -> 4079 bytes .../algorithms/time-complexity/extend.tar.gz | Bin 3912 -> 3913 bytes files/c/bonuses/03.tar.bz2 | Bin 2647 -> 2640 bytes files/c/bonuses/03.tar.gz | Bin 2337 -> 2336 bytes files/c/bonuses/04.tar.bz2 | Bin 2531 -> 2527 bytes files/c/bonuses/04.tar.gz | Bin 2499 -> 2500 bytes files/c/bonuses/05-06.tar.bz2 | Bin 3632 -> 3632 bytes files/c/bonuses/05-06.tar.gz | Bin 3487 -> 3487 bytes files/c/bonuses/08.tar.bz2 | Bin 73707 -> 74418 bytes files/c/bonuses/08.tar.gz | Bin 106322 -> 103594 bytes files/c/bonuses/10.tar.bz2 | Bin 234832 -> 234785 bytes files/c/bonuses/10.tar.gz | Bin 230127 -> 230116 bytes index.html | 4 +- search/index.html | 4 +- talks/index.html | 4 +- 146 files changed, 711 insertions(+), 711 deletions(-) create mode 100644 assets/js/1535ede8.b272bba2.js delete mode 100644 assets/js/1535ede8.cf110382.js create mode 100644 assets/js/595c7293.8b475e77.js delete mode 100644 assets/js/595c7293.e8aa1f47.js delete mode 100644 assets/js/7052c0bc.61d77968.js create mode 100644 assets/js/7052c0bc.cf9e5f57.js create mode 100644 assets/js/794ef108.083736fa.js delete mode 100644 assets/js/794ef108.8d36eaa9.js create mode 100644 assets/js/84d1e0d8.478c5852.js delete mode 100644 assets/js/84d1e0d8.f337d099.js delete mode 100644 assets/js/b1288602.19054c2d.js create mode 100644 assets/js/b1288602.9aa1a8e6.js create mode 100644 assets/js/d05e838c.0813f6b5.js delete mode 100644 assets/js/d05e838c.642ce149.js rename assets/js/{main.5d53fbfc.js => main.237fcc8a.js} (78%) rename assets/js/{main.5d53fbfc.js.LICENSE.txt => main.237fcc8a.js.LICENSE.txt} (100%) rename assets/js/{runtime~main.55537369.js => runtime~main.f2ae61cf.js} (95%) diff --git a/404.html b/404.html index 6c2e9b0..12b723a 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 d8b8044..e031fe5 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

@@ -26,7 +26,7 @@

To implement select sort from the exercises and make it as easy to read as possible, I have implemented maximum function that returns index of the biggest element from the first nn elements.

For the sake of time and memory complexity, I am also using itertools.islice, which makes a slice, but does not copy the elements into the memory like normal slice does.

There is also a check_loop_invariant function that will be described later.

-
def compare_by_value(pair):
index, value = pair
return value


def maximum(arr, n):
first_n_elements = itertools.islice(enumerate(arr), n)
index, value = max(first_n_elements, key=compare_by_value)
return index


def select_sort(arr, n):
assert n == len(arr)

check_loop_invariant(arr, n, n)
for i in reversed(range(1, n)):
j = maximum(arr, i + 1)
arr[i], arr[j] = arr[j], arr[i]

check_loop_invariant(arr, n, i)

return arr
+
def compare_by_value(pair):
index, value = pair
return value


def maximum(arr, n):
first_n_elements = itertools.islice(enumerate(arr), n)
index, value = max(first_n_elements, key=compare_by_value)
return index


def select_sort(arr, n):
assert n == len(arr)

check_loop_invariant(arr, n, n)
for i in reversed(range(1, n)):
j = maximum(arr, i + 1)
arr[i], arr[j] = arr[j], arr[i]

check_loop_invariant(arr, n, i)

return arr

Discussed preconditions, loop invariants and postconditions

You can safely replace A with arr or array for list.

Precondition

@@ -66,26 +66,26 @@
  • For each index from the end, I will assign maximum + index. This will ensure that even if the maximum in the original array was the first element, I will always satisfy that 2nd part of the loop invariant.
  • -
    def broken_select_sort(arr, n):
    assert n == len(arr)

    if not arr:
    return

    max_value = max(arr)

    check_loop_invariant(arr, n, n)
    for i in reversed(range(n)):
    arr[i] = max_value + i

    check_loop_invariant(arr, n, i)

    return arr
    +
    def broken_select_sort(arr, n):
    assert n == len(arr)

    if not arr:
    return

    max_value = max(arr)

    check_loop_invariant(arr, n, n)
    for i in reversed(range(n)):
    arr[i] = max_value + i

    check_loop_invariant(arr, n, i)

    return arr
    tip

    There is also an easier way to break this, I leave that as an exercise ;)

    Property-based tests for our sorts

    Since we have talked a lot about proofs at the seminar, I would like to demonstrate it on the testing of the sorts. In the following text I will cover implementation of the loop invariant and both postconditions we have talked about and then test our sorts using them.

    Loop invariant

    To check loop invariant I have implemented this function:

    -
    def check_loop_invariant(arr, n, i):
    # A[i + 1 : n] is sorted
    for x, y in zip(itertools.islice(arr, i + 1, n), itertools.islice(arr, i + 2, n)):
    assert x <= y

    # all elements of A[i + 1 : n] are bigger or equal to the other elements
    if i + 1 >= n:
    # in case there are no elements
    return

    # otherwise, since the "tail" is sorted, we can assume that it is enough to
    # check the other elements to the smallest value of the tail
    smallest = arr[i + 1]
    for element in itertools.islice(arr, i + 1):
    assert smallest >= element
    +
    def check_loop_invariant(arr, n, i):
    # A[i + 1 : n] is sorted
    for x, y in zip(itertools.islice(arr, i + 1, n), itertools.islice(arr, i + 2, n)):
    assert x <= y

    # all elements of A[i + 1 : n] are bigger or equal to the other elements
    if i + 1 >= n:
    # in case there are no elements
    return

    # otherwise, since the "tail" is sorted, we can assume that it is enough to
    # check the other elements to the smallest value of the tail
    smallest = arr[i + 1]
    for element in itertools.islice(arr, i + 1):
    assert smallest >= element

    First part checks if the "ending" of the array is sorted.

    In second part I have used a dirty trick of taking just the first element that is the smallest and compared the rest of the elements to it. Why is it enough? I leave it as an exercise ;)

    Postcondition(s)

    I have defined both the vague and explicit postconditions:

    -
    def check_vague_postcondition(original_arr, arr):
    if not arr:
    return

    # check ordering
    for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
    assert x <= y


    def check_postcondition(original_arr, arr):
    if not arr:
    return

    # check ordering
    for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
    assert x <= y

    # get counts from original list
    original_counts = {}
    for value in original_arr:
    original_counts[value] = 1 + original_counts.get(value, 0)

    # get counts from resulting list
    counts = {}
    for value in arr:
    counts[value] = 1 + counts.get(value, 0)

    # if arr is permutation of original_arr then all counts must be the same
    assert counts == original_counts
    +
    def check_vague_postcondition(original_arr, arr):
    if not arr:
    return

    # check ordering
    for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
    assert x <= y


    def check_postcondition(original_arr, arr):
    if not arr:
    return

    # check ordering
    for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
    assert x <= y

    # get counts from original list
    original_counts = {}
    for value in original_arr:
    original_counts[value] = 1 + original_counts.get(value, 0)

    # get counts from resulting list
    counts = {}
    for value in arr:
    counts[value] = 1 + counts.get(value, 0)

    # if arr is permutation of original_arr then all counts must be the same
    assert counts == original_counts

    Putting it together

    Now that we have everything implement, we can move on to the implementation of the tests:

    -
    from hypothesis import given, settings
    from hypothesis.strategies import integers, lists
    import pytest

    @given(lists(integers()))
    @settings(max_examples=1000)
    @pytest.mark.parametrize(
    "postcondition", [check_vague_postcondition, check_postcondition]
    )
    @pytest.mark.parametrize("sorting_function", [select_sort, broken_select_sort])
    def test_select_sort(sorting_function, postcondition, numbers):
    result = sorting_function(numbers[:], len(numbers))
    postcondition(numbers, result)
    +
    from hypothesis import given, settings
    from hypothesis.strategies import integers, lists
    import pytest

    @given(lists(integers()))
    @settings(max_examples=1000)
    @pytest.mark.parametrize(
    "postcondition", [check_vague_postcondition, check_postcondition]
    )
    @pytest.mark.parametrize("sorting_function", [select_sort, broken_select_sort])
    def test_select_sort(sorting_function, postcondition, numbers):
    result = sorting_function(numbers[:], len(numbers))
    postcondition(numbers, result)

    Since it might seem a bit scary, I will disect it by parts.

    1. Parameters of test function

      -
      def test_select_sort(sorting_function, postcondition, numbers):
      +
      def test_select_sort(sorting_function, postcondition, numbers):

      We are given 3 parameters:

      • sorting_function - as the name suggests is the sorting function we test
      • @@ -95,7 +95,7 @@ This will ensure that even if the maximum in the original array was the first el
      • Body of the test

        -
        result = sorting_function(numbers[:], len(numbers))
        postcondition(numbers, result)
        +
        result = sorting_function(numbers[:], len(numbers))
        postcondition(numbers, result)

        We pass to the sorting function copy of the numbers we got, this ensures that once we are checking the more strict postcondition, we can gather the necessary information even after sorting the list in-situ, i.e. we can check if the result is really a permutation of the numbers even though the sorting functions has modified the passed in list.

    @@ -103,7 +103,7 @@ This will ensure that even if the maximum in the original array was the first el
    1. 1st parametrize from the bottom

      -
      @pytest.mark.parametrize("sorting_function", [select_sort, broken_select_sort])
      +
      @pytest.mark.parametrize("sorting_function", [select_sort, broken_select_sort])

      This tells pytest, that we want to pass the values from the list to the parameter sorting_function. In other words, this lets us use the same test function for both the correct and incorrect select sort.

    2. @@ -120,7 +120,7 @@ This means hypothesis is randomly creating lists of integers and passing them to

    Let's run the tests!

    In case you want to experiment locally, you should install pytest and hypothesis from the PyPI.

    -
    % pytest -v test_sort.py
    =================================== test session starts ====================================
    platform linux -- Python 3.6.8, pytest-3.8.2, py-1.7.0, pluggy-0.13.1 -- /usr/bin/python3
    cachedir: .pytest_cache
    rootdir: /home/xfocko/git/xfocko/ib002/postcondition-ambiguity, inifile:
    plugins: hypothesis-5.16.1
    collected 4 items

    test_sort.py::test_select_sort[select_sort-check_vague_postcondition] PASSED [ 25%]
    test_sort.py::test_select_sort[select_sort-check_postcondition] PASSED [ 50%]
    test_sort.py::test_select_sort[broken_select_sort-check_vague_postcondition] PASSED [ 75%]
    test_sort.py::test_select_sort[broken_select_sort-check_postcondition] FAILED [100%]

    ========================================= FAILURES =========================================
    _________________ test_select_sort[broken_select_sort-check_postcondition] _________________

    sorting_function = <function broken_select_sort at 0x7fac179308c8>
    postcondition = <function check_postcondition at 0x7fac1786d1e0>

    @given(lists(integers()))
    > @settings(max_examples=1000)
    @pytest.mark.parametrize(
    "postcondition", [check_vague_postcondition, check_postcondition]
    )
    @pytest.mark.parametrize("sorting_function", [select_sort, broken_select_sort])
    def test_select_sort(sorting_function, postcondition, numbers):

    test_sort.py:132:
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    test_sort.py:139: in test_select_sort
    postcondition(numbers, result)
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    original_arr = [0, 0], arr = [0, 1]

    def check_postcondition(original_arr, arr):
    if not arr:
    return

    # check ordering
    for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
    assert x <= y

    # get counts from original list
    original_counts = {}
    for value in original_arr:
    original_counts[value] = 1 + original_counts.get(value, 0)

    # get counts from resulting list
    counts = {}
    for value in arr:
    counts[value] = 1 + counts.get(value, 0)

    # if arr is permutation of original_arr then all counts must be the same
    > assert counts == original_counts
    E assert {0: 1, 1: 1} == {0: 2}
    E Differing items:
    E {0: 1} != {0: 2}
    E Left contains more items:
    E {1: 1}
    E Full diff:
    E - {0: 1, 1: 1}
    E + {0: 2}

    test_sort.py:128: AssertionError
    ----------------------------------- Captured stdout call -----------------------------------
    Falsifying example: test_select_sort(
    sorting_function=<function test_sort.broken_select_sort>,
    postcondition=<function test_sort.check_postcondition>,
    numbers=[0, 0],
    )
    ============================ 1 failed, 3 passed in 6.84 seconds ============================
    +
    % pytest -v test_sort.py
    =================================== test session starts ====================================
    platform linux -- Python 3.6.8, pytest-3.8.2, py-1.7.0, pluggy-0.13.1 -- /usr/bin/python3
    cachedir: .pytest_cache
    rootdir: /home/xfocko/git/xfocko/ib002/postcondition-ambiguity, inifile:
    plugins: hypothesis-5.16.1
    collected 4 items

    test_sort.py::test_select_sort[select_sort-check_vague_postcondition] PASSED [ 25%]
    test_sort.py::test_select_sort[select_sort-check_postcondition] PASSED [ 50%]
    test_sort.py::test_select_sort[broken_select_sort-check_vague_postcondition] PASSED [ 75%]
    test_sort.py::test_select_sort[broken_select_sort-check_postcondition] FAILED [100%]

    ========================================= FAILURES =========================================
    _________________ test_select_sort[broken_select_sort-check_postcondition] _________________

    sorting_function = <function broken_select_sort at 0x7fac179308c8>
    postcondition = <function check_postcondition at 0x7fac1786d1e0>

    @given(lists(integers()))
    > @settings(max_examples=1000)
    @pytest.mark.parametrize(
    "postcondition", [check_vague_postcondition, check_postcondition]
    )
    @pytest.mark.parametrize("sorting_function", [select_sort, broken_select_sort])
    def test_select_sort(sorting_function, postcondition, numbers):

    test_sort.py:132:
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    test_sort.py:139: in test_select_sort
    postcondition(numbers, result)
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    original_arr = [0, 0], arr = [0, 1]

    def check_postcondition(original_arr, arr):
    if not arr:
    return

    # check ordering
    for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
    assert x <= y

    # get counts from original list
    original_counts = {}
    for value in original_arr:
    original_counts[value] = 1 + original_counts.get(value, 0)

    # get counts from resulting list
    counts = {}
    for value in arr:
    counts[value] = 1 + counts.get(value, 0)

    # if arr is permutation of original_arr then all counts must be the same
    > assert counts == original_counts
    E assert {0: 1, 1: 1} == {0: 2}
    E Differing items:
    E {0: 1} != {0: 2}
    E Left contains more items:
    E {1: 1}
    E Full diff:
    E - {0: 1, 1: 1}
    E + {0: 2}

    test_sort.py:128: AssertionError
    ----------------------------------- Captured stdout call -----------------------------------
    Falsifying example: test_select_sort(
    sorting_function=<function test_sort.broken_select_sort>,
    postcondition=<function test_sort.check_postcondition>,
    numbers=[0, 0],
    )
    ============================ 1 failed, 3 passed in 6.84 seconds ============================

    We can clearly see that our broken select sort has passed the vague postcondition, but the explicit one was not satisfied.

    Summary

    For proving the correctness of the algorithm it is better to be explicit than prove that algorithm is correct even though it is not. Being explicit also allows you to test smaller chunks of code better.

    diff --git a/algorithms/category/algorithms-and-correctness/index.html b/algorithms/category/algorithms-and-correctness/index.html index ba4cecf..3796859 100644 --- a/algorithms/category/algorithms-and-correctness/index.html +++ b/algorithms/category/algorithms-and-correctness/index.html @@ -18,8 +18,8 @@ correctness. - - + +
    Skip to main content

    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 4f050f4..aac9789 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 e76d81b..b8fbce4 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 09de777..d1433c5 100644 --- a/algorithms/category/hash-tables/index.html +++ b/algorithms/category/hash-tables/index.html @@ -16,8 +16,8 @@ - - + +

    Hash Tables

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

    Paths in Graphs

    Materials related to finding paths in graphs. diff --git a/algorithms/category/recursion/index.html b/algorithms/category/recursion/index.html index 5ecbe0a..327883e 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 479b1c1..af70dfa 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 5bdb394..faa1d31 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 0298c95..361209f 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

    @@ -28,17 +28,17 @@

    On the other hand, we have seen iterative implementation in the exercises and I have also prepared two from which one was similar to recursive implementation without colors from exercises and the other one used features of high-level languages.

    Different implementations

    Recursive DFS implementation from exercises without colors

    -
    function VisitedDFS(u: Vertex, visited: VertexSet) return VertexSet is
    v: Vertex;
    begin
    visited.Union(To_Set(u));

    for v in u.successors loop
    if not Contains(visited, v) then
    visited := visitedDFS(v, Visited);
    end if;
    end loop;

    return visited;
    end VisitedDFS;
    +
    function VisitedDFS(u: Vertex, visited: VertexSet) return VertexSet is
    v: Vertex;
    begin
    visited.Union(To_Set(u));

    for v in u.successors loop
    if not Contains(visited, v) then
    visited := visitedDFS(v, Visited);
    end if;
    end loop;

    return visited;
    end VisitedDFS;

    This implementation is correct, does the DFS traversal as it should, however it has one “smallish” downside and that is the time complexity. The usage of set raises the time complexity, of course it is implementation dependant. However in case of either RB-tree or hash-table implementation, we get look-up in time O(n)\mathcal{O}(n) for hash-table in worst-case or O(logn)\mathcal{O}(\log n) for the other in the worst-case. Both are not ideal compared to checking color on vertex.

    Iterative DFS from the exercises

    -
    procedure IterDFS(u: Vertex) is
    stack: StateVector;
    i, time: Integer;
    v: Vertex;
    begin
    stack.Append(VertexState(u, 0));
    u.color := Gray;
    time := 1;
    u.d := time;

    while not stack.Is_Empty loop
    u := stack.Last_Element.Vertex;
    i := stack.Last_Element.NextIndex;
    stack.Delete_Last;

    if i < u.successors.Length then
    -- search is not finished, is pushed back to stack
    stack.Append(VertexState(u, k + 1));

    v := u.successors.Element(i);
    if v.color = White then
    stack.Append(VertexState(v, 0));
    v.color := Gray;
    time := time + 1;
    v.d := time;
    end if;
    else
    -- u has no other successors, we can finish the search
    time := time + 1;
    u.f := time;
    u.color := Black;
    end if;
    end loop;

    end IterDFS;
    +
    procedure IterDFS(u: Vertex) is
    stack: StateVector;
    i, time: Integer;
    v: Vertex;
    begin
    stack.Append(VertexState(u, 0));
    u.color := Gray;
    time := 1;
    u.d := time;

    while not stack.Is_Empty loop
    u := stack.Last_Element.Vertex;
    i := stack.Last_Element.NextIndex;
    stack.Delete_Last;

    if i < u.successors.Length then
    -- search is not finished, is pushed back to stack
    stack.Append(VertexState(u, k + 1));

    v := u.successors.Element(i);
    if v.color = White then
    stack.Append(VertexState(v, 0));
    v.color := Gray;
    time := time + 1;
    v.d := time;
    end if;
    else
    -- u has no other successors, we can finish the search
    time := time + 1;
    u.f := time;
    u.color := Black;
    end if;
    end loop;

    end IterDFS;

    As we can see, there is some ordering in which we search through the successors. Time complexity is OK, stack holds at most all vertices (they must be on the current path).

    My iterative with path in stack

    -
    procedure DFS(start: Vertex) is
    path: VertexVector;
    time: Integer;
    hasSuccessor: Bool;
    successor: Vertex;
    begin
    path.Append(start);
    time := 1;

    start.d := time;
    start.color := Gray;

    while not path.Is_Empty loop
    hasSuccessor := false;

    for successor in path.Last_Element.successors loop
    if successor.color = White then
    hasSuccessor := true;

    successor.d := time + 1;
    successor.color := Gray;
    time := time + 1;

    path.Append(successor);

    exit;
    end if;
    end loop;

    if not hasSuccessor then
    path.Last_Element.f := time + 1;
    path.Last_Element.color := Black;

    time := time + 1;
    path.Delete_Last;
    end if;

    end loop;
    end DFS;
    +
    procedure DFS(start: Vertex) is
    path: VertexVector;
    time: Integer;
    hasSuccessor: Bool;
    successor: Vertex;
    begin
    path.Append(start);
    time := 1;

    start.d := time;
    start.color := Gray;

    while not path.Is_Empty loop
    hasSuccessor := false;

    for successor in path.Last_Element.successors loop
    if successor.color = White then
    hasSuccessor := true;

    successor.d := time + 1;
    successor.color := Gray;
    time := time + 1;

    path.Append(successor);

    exit;
    end if;
    end loop;

    if not hasSuccessor then
    path.Last_Element.f := time + 1;
    path.Last_Element.color := Black;

    time := time + 1;
    path.Delete_Last;
    end if;

    end loop;
    end DFS;

    This approach is similar to the iterative solution from the exercises, but it does not keep the index of the next successor, therefore it always iterates through all of them, which raises the time complexity.

    My iterative solution with iterators

    On the other hand, we do not actually have to depend on the representation of the graph. In this case, we just somehow obtain the iterator (which yields all of the succesors) and keep it in the stack.

    -
    procedure DFS(start: Vertex) is
    path: StateVector;
    time: Integer;
    current: State;
    nextVertex: Vertex;
    begin
    path.Append(State(start));
    time := 1;

    start.d := time;
    start.color := Gray;

    while not path.Is_Empty loop
    current := path.Last_Element;

    if not Move_Next(current.successors) then
    path.Delete_Last;

    time := time + 1;
    current.vertex.f := time;

    current.vertex.color := Black;
    else if current.successors.Value.color = white then
    nextVertex := current.successors.Value;

    time := time + 1;
    nextVertex.d := time;

    nextVertex.color := Gray;

    path.Append(State(nextVertex));
    end if;
    end loop;
    end DFS;
    +
    procedure DFS(start: Vertex) is
    path: StateVector;
    time: Integer;
    current: State;
    nextVertex: Vertex;
    begin
    path.Append(State(start));
    time := 1;

    start.d := time;
    start.color := Gray;

    while not path.Is_Empty loop
    current := path.Last_Element;

    if not Move_Next(current.successors) then
    path.Delete_Last;

    time := time + 1;
    current.vertex.f := time;

    current.vertex.color := Black;
    else if current.successors.Value.color = white then
    nextVertex := current.successors.Value;

    time := time + 1;
    nextVertex.d := time;

    nextVertex.color := Gray;

    path.Append(State(nextVertex));
    end if;
    end loop;
    end DFS;

    ( The way we manipulate with the iterators is closest to the C# implementation. Apart from the Iterator thing :) In case you tried to implement it in C++, you would more than likely need to change the check, since you would get first successor right at the beginning )

    So here we don't keep indices, but the iterators. We can also check existence of other successors easily: by the iterator moving after the last successor.

    Closer explanation of the iterator shenanigans follows. In the beginning, either start or when pushing new vertex, we are pushing an iterator that points just before the first successor. When populating lastVertex and successors in the while-loop, we take the element from the top of the stack. MoveNext returns true if there is an element, i.e. successor in this case. If it returns false we have nothing to do and we pop the vertex from the stack (also set finishing time and color). If we have successor we check if it has been already visited or not. If has not, we set discovery time and color accordingly, also we add it to stack.

    diff --git a/algorithms/hash-tables/breaking/index.html b/algorithms/hash-tables/breaking/index.html index b906f2e..1072b09 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 @@ -87,7 +87,7 @@ plays a crucial role, but there are also different ways how you can implement a hash table, so we will have a look at those too.

    Hash functions

    info

    We will start with a definition of hash function in a mathematical definition -and type signature in some known language:

    h:TN h : T \rightarrow \mathbb{N}

    For a type signature we will just take the declaration from C++7:

    std::size_t operator()(const T& key) const;

    If you compare with the mathematical definition, it is very similar, except for +and type signature in some known language:

    h:TN h : T \rightarrow \mathbb{N}

    For a type signature we will just take the declaration from C++7:

    std::size_t operator()(const T& key) const;

    If you compare with the mathematical definition, it is very similar, except for the fact that the memory is not unlimited, so the natural number turned into an unsigned integer type (on majority of platforms it will be a 64-bit unsigned integer).

    @@ -112,10 +112,10 @@ powers of 2 which allows bit-masking to take place.

    Example

    Let's say we're given h = 0xDEADBEEF and we have l = 65536=2^16 spots in our hash table. What can we do here?

    Well, we definitely have a bigger hash than spots available, so we need to “shrink” it somehow. The most common practice is to take the lower bits of the -hash to represent an index in the table:

    h & (l - 1)

    Why does this work? Firstly we subtract 1 from the length (indices run from +hash to represent an index in the table:

    h & (l - 1)

    Why does this work? Firstly we subtract 1 from the length (indices run from ⟨0 ; l - 1⟩, since table is zero-indexed). Therefore if we do binary and on any number, we always get a valid index within the table. Let's find the index -for our hash:

    0xDEADBEEF & 0xFFFF = 0xBEEF
    +for our hash:

    0xDEADBEEF & 0xFFFF = 0xBEEF

    Footnotes

    1. diff --git a/algorithms/hash-tables/breaking/mitigations/index.html b/algorithms/hash-tables/breaking/mitigations/index.html index 0d747f9..7e92ff5 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 @@ -27,17 +27,17 @@ topic; in references below) I will use the C++ to describe the mitigations.

      Random seed

      One of the options how to avoid this kind of an attack is to introduce a random seed to the hash. That way it is not that easy to choose the nasty numbers.

      -
      struct custom_hash {
      size_t operator()(uint64_t x) const {
      return x + 7529;
      }
      };
      +
      struct custom_hash {
      size_t operator()(uint64_t x) const {
      return x + 7529;
      }
      };

      As you may have noticed, this is not very helpful, since it just shifts the issue by some number. Better option is to use a shift from random number generator:

      -
      struct custom_hash {
      size_t operator()(uint64_t x) const {
      static const uint64_t FIXED_RANDOM =
      chrono::steady_clock::now().time_since_epoch().count();
      return x + FIXED_RANDOM;
      }
      };
      +
      struct custom_hash {
      size_t operator()(uint64_t x) const {
      static const uint64_t FIXED_RANDOM =
      chrono::steady_clock::now().time_since_epoch().count();
      return x + FIXED_RANDOM;
      }
      };

      In this case the hash is using a high-precision clock to shift the number, which is much harder to break.

      Better random seed

      Building on the previous solution, we can do some bit magic instead of the shifting:

      -
      struct custom_hash {
      size_t operator()(uint64_t x) const {
      static const uint64_t FIXED_RANDOM =
      chrono::steady_clock::now().time_since_epoch().count();
      x ^= FIXED_RANDOM;
      return x ^ (x >> 16);
      }
      };
      +
      struct custom_hash {
      size_t operator()(uint64_t x) const {
      static const uint64_t FIXED_RANDOM =
      chrono::steady_clock::now().time_since_epoch().count();
      x ^= FIXED_RANDOM;
      return x ^ (x >> 16);
      }
      };

      This not only shifts the number, it also manipulates the underlying bits of the hash. In this case we're also applying the XOR operation.

      Adjusting the hash function

      @@ -46,18 +46,18 @@ hash. In this case we're also applying the XOR operation.

      default.

      On the other hand, you can usually specify your own hash function, here we will follow the article by Neal that uses so-called splitmix64.

      -
      static uint64_t splitmix64(uint64_t x) {
      // http://xorshift.di.unimi.it/splitmix64.c
      x += 0x9e3779b97f4a7c15;
      x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
      x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
      return x ^ (x >> 31);
      }
      +
      static uint64_t splitmix64(uint64_t x) {
      // http://xorshift.di.unimi.it/splitmix64.c
      x += 0x9e3779b97f4a7c15;
      x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
      x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
      return x ^ (x >> 31);
      }

      As you can see, this definitely doesn't do identity on the integers 😄

      Another example would be HashMap::hash() function in Java:

      -
      /**
      * Computes key.hashCode() and spreads (XORs) higher bits of hash
      * to lower. Because the table uses power-of-two masking, sets of
      * hashes that vary only in bits above the current mask will
      * always collide. (Among known examples are sets of Float keys
      * holding consecutive whole numbers in small tables.) So we
      * apply a transform that spreads the impact of higher bits
      * downward. There is a tradeoff between speed, utility, and
      * quality of bit-spreading. Because many common sets of hashes
      * are already reasonably distributed (so don't benefit from
      * spreading), and because we use trees to handle large sets of
      * collisions in bins, we just XOR some shifted bits in the
      * cheapest possible way to reduce systematic lossage, as well as
      * to incorporate impact of the highest bits that would otherwise
      * never be used in index calculations because of table bounds.
      */
      static final int hash(Object key) {
      int h;
      return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
      }
      +
      /**
      * Computes key.hashCode() and spreads (XORs) higher bits of hash
      * to lower. Because the table uses power-of-two masking, sets of
      * hashes that vary only in bits above the current mask will
      * always collide. (Among known examples are sets of Float keys
      * holding consecutive whole numbers in small tables.) So we
      * apply a transform that spreads the impact of higher bits
      * downward. There is a tradeoff between speed, utility, and
      * quality of bit-spreading. Because many common sets of hashes
      * are already reasonably distributed (so don't benefit from
      * spreading), and because we use trees to handle large sets of
      * collisions in bins, we just XOR some shifted bits in the
      * cheapest possible way to reduce systematic lossage, as well as
      * to incorporate impact of the highest bits that would otherwise
      * never be used in index calculations because of table bounds.
      */
      static final int hash(Object key) {
      int h;
      return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
      }

      You can notice that they try to include the upper bits of the hash by using XOR, this would render our attack in the previous part helpless.

      Combining both

      Can we make it better? Of course! Use multiple mitigations at the same time. In our case, we will both inject the random value and use the splitmix64:

      -
      struct custom_hash {
      static uint64_t splitmix64(uint64_t x) {
      // http://xorshift.di.unimi.it/splitmix64.c
      x += 0x9e3779b97f4a7c15;
      x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
      x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
      return x ^ (x >> 31);
      }

      size_t operator()(uint64_t x) const {
      static const uint64_t FIXED_RANDOM =
      chrono::steady_clock::now().time_since_epoch().count();
      return splitmix64(x + FIXED_RANDOM);
      }
      };
      +
      struct custom_hash {
      static uint64_t splitmix64(uint64_t x) {
      // http://xorshift.di.unimi.it/splitmix64.c
      x += 0x9e3779b97f4a7c15;
      x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
      x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
      return x ^ (x >> 31);
      }

      size_t operator()(uint64_t x) const {
      static const uint64_t FIXED_RANDOM =
      chrono::steady_clock::now().time_since_epoch().count();
      return splitmix64(x + FIXED_RANDOM);
      }
      };

      Fallback for extreme cases

      As we have mentioned above, Python resolves the conflicts by probing (it looks for empty space somewhere else in the table, but it's deterministic about it, so diff --git a/algorithms/hash-tables/breaking/python/index.html b/algorithms/hash-tables/breaking/python/index.html index 374e4a9..495e728 100644 --- a/algorithms/hash-tables/breaking/python/index.html +++ b/algorithms/hash-tables/breaking/python/index.html @@ -16,8 +16,8 @@ - - + +

    2. up for 10 times in a row.

      As a base of our benchmark, we will use a Strategy class and then for each strategy we will just implement the sequence of numbers that it uses:

      -
      class Strategy:
      def __init__(self, data_structure=set):
      self._table = data_structure()

      @cached_property
      def elements(self):
      raise NotImplementedError("Implement for each strategy")

      @property
      def name(self):
      raise NotImplementedError("Implement for each strategy")

      def run(self):
      print(f"\nBenchmarking:\t\t{self.name}")

      # Extract the elements here, so that the evaluation of them does not
      # slow down the relevant part of benchmark
      elements = self.elements

      # Insertion phase
      start = monotonic_ns()
      for x in elements:
      self._table.add(x)
      after_insertion = monotonic_ns()

      print(f"Insertion phase:\t{(after_insertion - start) / 1000000:.2f}ms")

      # Lookup phase
      start = monotonic_ns()
      for _ in range(LOOPS):
      for x in elements:
      assert x in self._table
      after_lookups = monotonic_ns()

      print(f"Lookup phase:\t\t{(after_lookups - start) / 1000000:.2f}ms")
      +
      class Strategy:
      def __init__(self, data_structure=set):
      self._table = data_structure()

      @cached_property
      def elements(self):
      raise NotImplementedError("Implement for each strategy")

      @property
      def name(self):
      raise NotImplementedError("Implement for each strategy")

      def run(self):
      print(f"\nBenchmarking:\t\t{self.name}")

      # Extract the elements here, so that the evaluation of them does not
      # slow down the relevant part of benchmark
      elements = self.elements

      # Insertion phase
      start = monotonic_ns()
      for x in elements:
      self._table.add(x)
      after_insertion = monotonic_ns()

      print(f"Insertion phase:\t{(after_insertion - start) / 1000000:.2f}ms")

      # Lookup phase
      start = monotonic_ns()
      for _ in range(LOOPS):
      for x in elements:
      assert x in self._table
      after_lookups = monotonic_ns()

      print(f"Lookup phase:\t\t{(after_lookups - start) / 1000000:.2f}ms")

      Sequences

      Let's have a look at how we generate the numbers to be inserted:

      • ordered sequence (ascending) -
        x for x in range(N_ELEMENTS)
        +
        x for x in range(N_ELEMENTS)
      • ordered sequence (descending) -
        x for x in reversed(range(N_ELEMENTS))
        +
        x for x in reversed(range(N_ELEMENTS))
      • progressive sequence that “heals” on resize -
        (x << max(5, x.bit_length())) for x in range(N_ELEMENTS)
        +
        (x << max(5, x.bit_length())) for x in range(N_ELEMENTS)
      • progressive sequence that “heals” in the end -
        (x << max(5, x.bit_length())) for x in reversed(range(N_ELEMENTS))
        +
        (x << max(5, x.bit_length())) for x in reversed(range(N_ELEMENTS))
      • conflicts everywhere -
        x << 32 for x in range(N_ELEMENTS)
        +
        x << 32 for x in range(N_ELEMENTS)

      Results

      diff --git a/algorithms/index.html b/algorithms/index.html index b770774..0d9e090 100644 --- a/algorithms/index.html +++ b/algorithms/index.html @@ -14,8 +14,8 @@ - - + +

      Introduction

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

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

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

      +in the linked GitLab.

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

    A* algorithm

    Intro

    @@ -73,20 +73,20 @@ the actual steps from the goal.

    calculate the shortest path and pass the heuristic as a parameter.

    Implementation

    Actual implementation is very easy once we have the Dijkstra's algorithm:

    -
    auto astar(const graph& g, const vertex_t& source, const auto& h)
    -> std::vector<std::vector<int>> {
    // make sure that ‹source› exists
    assert(g.has(source));

    // initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // initialize the visited
    std::vector<std::vector<bool>> visited(g.height(),
    std::vector(g.width(), false));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    pqueue_t priority_queue{std::make_pair(0 + h(source), source)};
    std::optional<pqueue_item_t> item{};
    while ((item = popq(priority_queue))) {
    auto [cost, u] = *item;
    auto [x, y] = u;

    // we have already found the shortest path
    if (visited[y][x]) {
    continue;
    }
    visited[y][x] = true;

    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it and update queue
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    pushq(priority_queue,
    std::make_pair(distances[y + dy][x + dx] + h(v), v));
    }
    }
    }

    return distances;
    }
    +
    auto astar(const graph& g, const vertex_t& source, const auto& h)
    -> std::vector<std::vector<int>> {
    // make sure that ‹source› exists
    assert(g.has(source));

    // initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // initialize the visited
    std::vector<std::vector<bool>> visited(g.height(),
    std::vector(g.width(), false));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    pqueue_t priority_queue{std::make_pair(0 + h(source), source)};
    std::optional<pqueue_item_t> item{};
    while ((item = popq(priority_queue))) {
    auto [cost, u] = *item;
    auto [x, y] = u;

    // we have already found the shortest path
    if (visited[y][x]) {
    continue;
    }
    visited[y][x] = true;

    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it and update queue
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    pushq(priority_queue,
    std::make_pair(distances[y + dy][x + dx] + h(v), v));
    }
    }
    }

    return distances;
    }

    Running on our map

    For this algorithm I will also show the example of a call:

    -
    distances = astar(g, std::make_pair(1, 9), [](const auto& u) {
    auto [x, y] = u;
    return std::abs(1 - x) + std::abs(7 - y);
    });
    std::cout << "[A*] Cost: " << distances[7][1] << "\n";
    +
    distances = astar(g, std::make_pair(1, 9), [](const auto& u) {
    auto [x, y] = u;
    return std::abs(1 - x) + std::abs(7 - y);
    });
    std::cout << "[A*] Cost: " << distances[7][1] << "\n";

    First argument to the function is the graph itself. Second argument is the source vertex where we start. And finally the lambda returns Manhattan distance to the goal.

    And we get the following result:

    -
    Normal cost: 1
    Vortex cost: 5
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    [Finite BF] Cost: 22
    [Bellman-Ford] Cost: 22
    [Dijkstra] Cost: 22
    [A*] Cost: 22
    +
    Normal cost: 1
    Vortex cost: 5
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    [Finite BF] Cost: 22
    [Bellman-Ford] Cost: 22
    [Dijkstra] Cost: 22
    [A*] Cost: 22

    Comparison

    Now you may wonder how does it compare to the previous algorithms. Supposedly it should be faster. Let's add counters and debugging output when we update distance to our goal. And now if we run our code, we get the following output:

    -
    Normal cost: 1
    Vortex cost: 5
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    Relaxing path to goal in 40. relaxation
    Relaxing path to goal in 68. relaxation
    Relaxing path to goal in 89. relaxation
    [Finite BF] Cost: 22
    Relaxing path to goal in 40. relaxation
    Relaxing path to goal in 68. relaxation
    Relaxing path to goal in 89. relaxation
    [Bellman-Ford] Cost: 22
    Relaxing path to goal in 41. iteration
    [Dijkstra] Cost: 22
    Relaxing path to goal in 31. iteration
    [A*] Cost: 22
    +
    Normal cost: 1
    Vortex cost: 5
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    Relaxing path to goal in 40. relaxation
    Relaxing path to goal in 68. relaxation
    Relaxing path to goal in 89. relaxation
    [Finite BF] Cost: 22
    Relaxing path to goal in 40. relaxation
    Relaxing path to goal in 68. relaxation
    Relaxing path to goal in 89. relaxation
    [Bellman-Ford] Cost: 22
    Relaxing path to goal in 41. iteration
    [Dijkstra] Cost: 22
    Relaxing path to goal in 31. iteration
    [A*] Cost: 22

    From the output we can easily deduce that for both brute-force and Bellman-Ford, which are in our case identical, we actually relax three times and for the last time in the 89th iteration.

    diff --git a/algorithms/paths/bf-to-astar/bf/index.html b/algorithms/paths/bf-to-astar/bf/index.html index 6cbc407..7c0df27 100644 --- a/algorithms/paths/bf-to-astar/bf/index.html +++ b/algorithms/paths/bf-to-astar/bf/index.html @@ -18,8 +18,8 @@ something. - - + +

    BF

    Basic idea

    @@ -37,7 +37,7 @@ highest possible price) and try to improve what we've gotten so far until t are no improvements. That sounds fine, we shall implement this. Since we are going on repeat, we will name this function bf() as in brute-force, cause it is trying to find it the hard way:

    -
    const static std::vector<vertex_t> DIRECTIONS =
    std::vector{std::make_pair(0, 1), std::make_pair(0, -1),
    std::make_pair(1, 0), std::make_pair(-1, 0)};

    auto bf(const graph& g, const vertex_t& source, const vertex_t& destination)
    -> int {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // ‹destination› must be within the bounds
    assert(g.has(destination));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we need to improve the paths as long as possible
    bool improvement_found;
    do {
    // reset the flag at the beginning
    improvement_found = false;

    // go through all of the vertices
    for (int y = 0; y < g.height(); ++y) {
    for (int x = 0; x < g.width(); ++x) {
    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    continue;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    improvement_found = true;
    }
    }
    }
    }
    } while (improvement_found);

    return distances[destination.second][destination.first];
    }
    +
    const static std::vector<vertex_t> DIRECTIONS =
    std::vector{std::make_pair(0, 1), std::make_pair(0, -1),
    std::make_pair(1, 0), std::make_pair(-1, 0)};

    auto bf(const graph& g, const vertex_t& source, const vertex_t& destination)
    -> int {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // ‹destination› must be within the bounds
    assert(g.has(destination));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we need to improve the paths as long as possible
    bool improvement_found;
    do {
    // reset the flag at the beginning
    improvement_found = false;

    // go through all of the vertices
    for (int y = 0; y < g.height(); ++y) {
    for (int x = 0; x < g.width(); ++x) {
    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    continue;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    improvement_found = true;
    }
    }
    }
    }
    } while (improvement_found);

    return distances[destination.second][destination.first];
    }
    Relaxation

    I have made a brief mention of the relaxation in the comment in the code. You've been probably thought that relaxation of an edge means that you found a better solution to the problem.

    In general it is an approximation technique that reduces the problem of @@ -47,13 +47,13 @@ finding the path u → x1 → … → xn → v to subproblems

    Correctness

    Is our solution correct? It appears to be correct… We have rather complicated map and our algorithm has finished in an instant with the following output:

    -
    Normal cost: 1
    Vortex cost: 5
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    Cost: 22
    +
    Normal cost: 1
    Vortex cost: 5
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    Cost: 22

    If you have a better look at the map, you will realize that the cost 22 is the one path skipping the * cells, since they cost more than going around.

    We can play around a bit with it. The * cells can be even vortices that pull you in with a negative price and let you propel yourself out 😉 Let's change their cost to -1 then. Let's check what's the fastest path to the cell.

    -
    Normal cost: 1
    Vortex cost: -1
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    +
    Normal cost: 1
    Vortex cost: -1
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############

    And we're somehow stuck… The issue comes from the fact that spinning around in the vortices allows us to lower the cost infinitely. That's why after each iteration there is still a possibility to lower the cost, hence the algorithm @@ -90,9 +90,9 @@ iterations, is the effect of a negative loop in the graph.

    How can we leverage this? We will go through the edges only as many times as cells we have. Let's adjust the code to fix the looping:

    -
    auto bf_finite(const graph& g, const vertex_t& source,
    const vertex_t& destination) -> int {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // ‹destination› must be within the bounds
    assert(g.has(destination));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we only iterate as many times as cells that we have
    for (int i = g.height() * g.width(); i > 0; --i) {
    // go through all of the vertices
    for (int y = 0; y < g.height(); ++y) {
    for (int x = 0; x < g.width(); ++x) {
    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    continue;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    }
    }
    }
    }
    }

    return distances[destination.second][destination.first];
    }
    +
    auto bf_finite(const graph& g, const vertex_t& source,
    const vertex_t& destination) -> int {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // ‹destination› must be within the bounds
    assert(g.has(destination));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we only iterate as many times as cells that we have
    for (int i = g.height() * g.width(); i > 0; --i) {
    // go through all of the vertices
    for (int y = 0; y < g.height(); ++y) {
    for (int x = 0; x < g.width(); ++x) {
    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    continue;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    }
    }
    }
    }
    }

    return distances[destination.second][destination.first];
    }

    And we get the following result:

    -
    Normal cost: 1
    Vortex cost: -1
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    Cost: -236
    +
    Normal cost: 1
    Vortex cost: -1
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    Cost: -236

    The negative cost means that there is a way to propel ourselves via some vortices. Let's adjust the cost of vortices back to the original 5 and check whether our modified algorithm works as it did before. And it surely does yield @@ -100,7 +100,7 @@ the 22 as before.

    Refactoring

    You can definitely notice some deep nesting in our code, to counter this phenomenon I will convert the looping over x and y to one variable that can be decomposed to x and y. It is a very common practice when working with 2D -arrays/lists to represent them as 1D. In our case:

    i : 0 → width * height - 1
    x = i % width
    y = i / width
    +arrays/lists to represent them as 1D. In our case:

    i : 0 → width * height - 1
    x = i % width
    y = i / width

    Bellman-Ford

    If you have ever attended any Algorithms course that had path-finding in its syllabus, you probably feel like you've seen the algorithm above before3… And @@ -110,9 +110,9 @@ prevention we got to the point that is almost the Bellman-Ford with the exception that it doesn't report whether there are any negative cycles, it just ends.

    Let's have a look at a proper implementation of the Bellman-Ford algorithm:

    -
    auto bellman_ford(const graph& g, const vertex_t& source)
    -> std::vector<std::vector<int>> {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we only iterate as many times as cells that we have
    for (int i = g.height() * g.width(); i > 0; --i) {
    // go through all of the vertices
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    int y = v / g.width();
    int x = v % g.width();

    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    continue;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    }
    }
    }
    }

    // now we check for the negative loops
    bool relaxed = false;
    for (int v = g.height() * g.width() - 1; !relaxed && v >= 0; --v) {
    int y = v / g.width();
    int x = v % g.width();

    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    continue;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    relaxed = true;
    std::cerr << "Found a negative loop\n";
    break;
    }
    }
    }

    return distances;
    }
    +
    auto bellman_ford(const graph& g, const vertex_t& source)
    -> std::vector<std::vector<int>> {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we only iterate as many times as cells that we have
    for (int i = g.height() * g.width(); i > 0; --i) {
    // go through all of the vertices
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    int y = v / g.width();
    int x = v % g.width();

    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    continue;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    }
    }
    }
    }

    // now we check for the negative loops
    bool relaxed = false;
    for (int v = g.height() * g.width() - 1; !relaxed && v >= 0; --v) {
    int y = v / g.width();
    int x = v % g.width();

    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    continue;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    relaxed = true;
    std::cerr << "Found a negative loop\n";
    break;
    }
    }
    }

    return distances;
    }

    And if we run it with our negative cost of entering vortices:

    -
    [Bellman-Ford] Found a negative loop
    [Bellman-Ford] Cost: -240
    +
    [Bellman-Ford] Found a negative loop
    [Bellman-Ford] Cost: -240

    On the Bellman-Ford

    You might be surprised that we have managed to iterate from a brute-force method that mindlessly tries to find a better path until there are no better paths left @@ -153,13 +153,13 @@ worst-case ordering of the relaxations which results in

    Small refactor

    Since we are literally copy-pasting the body of the loops just for the sake of relaxing, we can factor that part out into a separate function:

    -
    static auto _check_vertex(const graph& g,
    std::vector<std::vector<int>>& distances, int v,
    bool check_only = false) -> bool {
    bool improvement_found = false;

    // unpack the vertex coordinates
    int y = v / g.width();
    int x = v % g.width();

    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    return false;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    if (check_only) {
    return true;
    }

    distances[y + dy][x + dx] = distances[y][x] + cost;
    improvement_found = true;
    }
    }

    return improvement_found;
    }
    +
    static auto _check_vertex(const graph& g,
    std::vector<std::vector<int>>& distances, int v,
    bool check_only = false) -> bool {
    bool improvement_found = false;

    // unpack the vertex coordinates
    int y = v / g.width();
    int x = v % g.width();

    // skip the cells we cannot reach
    if (distances[y][x] == graph::unreachable()) {
    return false;
    }

    // go through the neighbours
    auto u = std::make_pair(x, y);
    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    if (check_only) {
    return true;
    }

    distances[y + dy][x + dx] = distances[y][x] + cost;
    improvement_found = true;
    }
    }

    return improvement_found;
    }

    This function can be also used for checking the negative loops at the end of the BF by using the check_only parameter to signal that we just want to know if there would be any edge relaxed instead of performing the relaxation itself.

    Then we can also see the differences between the specific versions of our path-finding algorithms in a clear way:

    -
    auto bf(const graph& g, const vertex_t& source, const vertex_t& destination)
    -> int {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // ‹destination› must be within the bounds
    assert(g.has(destination));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we need to improve the paths as long as possible
    bool improvement_found;
    do {
    // reset the flag at the beginning
    improvement_found = false;

    // go through all of the vertices
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    improvement_found = _check_vertex(g, distances, v) || improvement_found;
    }
    } while (improvement_found);

    return distances[destination.second][destination.first];
    }

    auto bf_finite(const graph& g, const vertex_t& source,
    const vertex_t& destination) -> int {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // ‹destination› must be within the bounds
    assert(g.has(destination));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we only iterate as many times as cells that we have
    for (int i = g.height() * g.width(); i > 0; --i) {
    // go through all of the vertices
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    _check_vertex(g, distances, v);
    }
    }

    return distances[destination.second][destination.first];
    }

    auto bellman_ford(const graph& g, const vertex_t& source)
    -> std::vector<std::vector<int>> {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we only iterate as many times as cells that we have
    for (int i = g.height() * g.width(); i > 0; --i) {
    // go through all of the vertices
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    _check_vertex(g, distances, v);
    }
    }

    // now we check for the negative loops
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    if (_check_vertex(g, distances, v, true)) {
    std::cerr << "[Bellman-Ford] Found a negative loop\n";
    break;
    }
    }

    return distances;
    }

    +
    auto bf(const graph& g, const vertex_t& source, const vertex_t& destination)
    -> int {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // ‹destination› must be within the bounds
    assert(g.has(destination));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we need to improve the paths as long as possible
    bool improvement_found;
    do {
    // reset the flag at the beginning
    improvement_found = false;

    // go through all of the vertices
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    improvement_found = _check_vertex(g, distances, v) || improvement_found;
    }
    } while (improvement_found);

    return distances[destination.second][destination.first];
    }

    auto bf_finite(const graph& g, const vertex_t& source,
    const vertex_t& destination) -> int {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // ‹destination› must be within the bounds
    assert(g.has(destination));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we only iterate as many times as cells that we have
    for (int i = g.height() * g.width(); i > 0; --i) {
    // go through all of the vertices
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    _check_vertex(g, distances, v);
    }
    }

    return distances[destination.second][destination.first];
    }

    auto bellman_ford(const graph& g, const vertex_t& source)
    -> std::vector<std::vector<int>> {
    // ‹source› must be within the bounds
    assert(g.has(source));

    // we need to initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    // now we only iterate as many times as cells that we have
    for (int i = g.height() * g.width(); i > 0; --i) {
    // go through all of the vertices
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    _check_vertex(g, distances, v);
    }
    }

    // now we check for the negative loops
    for (int v = g.height() * g.width() - 1; v >= 0; --v) {
    if (_check_vertex(g, distances, v, true)) {
    std::cerr << "[Bellman-Ford] Found a negative loop\n";
    break;
    }
    }

    return distances;
    }


    tip

    You might've noticed that I've been using abbreviation BF interchangeably for both Bellman-Ford and brute-force. If you think about the way Bellman-Ford diff --git a/algorithms/paths/bf-to-astar/dijkstra/index.html b/algorithms/paths/bf-to-astar/dijkstra/index.html index 2b6e909..3ef6965 100644 --- a/algorithms/paths/bf-to-astar/dijkstra/index.html +++ b/algorithms/paths/bf-to-astar/dijkstra/index.html @@ -16,8 +16,8 @@ - - + +

    Dijkstra's algorithm

    Intro

    @@ -62,7 +62,7 @@ precondition is required because of the nature of the algorithm that requires monotonically non-decreasing changes in the costs of shortest paths.

    Short description

    Let's have a brief look at the pseudocode taken from the Wikipedia:

    -
    function Dijkstra(Graph, source):
    for each vertex v in Graph.Vertices:
    dist[v] ← INFINITY
    prev[v] ← UNDEFINED
    add v to Q
    dist[source] ← 0

    while Q is not empty:
    u ← vertex in Q with min dist[u]
    remove u from Q

    for each neighbor v of u still in Q:
    alt ← dist[u] + Graph.Edges(u, v)
    if alt < dist[v]:
    dist[v] ← alt
    prev[v] ← u

    return dist[], prev[]
    +
    function Dijkstra(Graph, source):
    for each vertex v in Graph.Vertices:
    dist[v] ← INFINITY
    prev[v] ← UNDEFINED
    add v to Q
    dist[source] ← 0

    while Q is not empty:
    u ← vertex in Q with min dist[u]
    remove u from Q

    for each neighbor v of u still in Q:
    alt ← dist[u] + Graph.Edges(u, v)
    if alt < dist[v]:
    dist[v] ← alt
    prev[v] ← u

    return dist[], prev[]

    Dijkstra's algorithm works in such way that it always tries to find the shortest paths from a vertex to which it already has a shortest path. This may result in finding the shortest path to another vertex, or at least some path, till further @@ -95,10 +95,10 @@ may have a higher cost, but the outgoing edge compensates for it.

    functions that can be used for maintaining max heaps. They also have generalized version with any ordering, in our case we need reverse ordering, because we need the min heap.

    -
    using pqueue_item_t = std::pair<int, vertex_t>;
    using pqueue_t = std::vector<pqueue_item_t>;

    auto pushq(pqueue_t& q, pqueue_item_t v) -> void {
    q.push_back(v);
    std::push_heap(q.begin(), q.end(), std::greater<>{});
    }

    auto popq(pqueue_t& q) -> std::optional<pqueue_item_t> {
    if (q.empty()) {
    return {};
    }

    std::pop_heap(q.begin(), q.end(), std::greater<>{});
    pqueue_item_t top = q.back();
    q.pop_back();

    return std::make_optional(top);
    }
    +
    using pqueue_item_t = std::pair<int, vertex_t>;
    using pqueue_t = std::vector<pqueue_item_t>;

    auto pushq(pqueue_t& q, pqueue_item_t v) -> void {
    q.push_back(v);
    std::push_heap(q.begin(), q.end(), std::greater<>{});
    }

    auto popq(pqueue_t& q) -> std::optional<pqueue_item_t> {
    if (q.empty()) {
    return {};
    }

    std::pop_heap(q.begin(), q.end(), std::greater<>{});
    pqueue_item_t top = q.back();
    q.pop_back();

    return std::make_optional(top);
    }

    And now we can finally move to the actual implementation of the Dijkstra's algorithm:

    -
    auto dijkstra(const graph& g, const vertex_t& source)
    -> std::vector<std::vector<int>> {
    // make sure that ‹source› exists
    assert(g.has(source));

    // initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // initialize the visited
    std::vector<std::vector<bool>> visited(g.height(),
    std::vector(g.width(), false));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    pqueue_t priority_queue{std::make_pair(0, source)};
    std::optional<pqueue_item_t> item{};
    while ((item = popq(priority_queue))) {
    auto [cost, u] = *item;
    auto [x, y] = u;

    // we have already found the shortest path
    if (visited[y][x]) {
    continue;
    }
    visited[y][x] = true;

    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it and update queue
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    pushq(priority_queue, std::make_pair(distances[y + dy][x + dx], v));
    }
    }
    }

    return distances;
    }
    +
    auto dijkstra(const graph& g, const vertex_t& source)
    -> std::vector<std::vector<int>> {
    // make sure that ‹source› exists
    assert(g.has(source));

    // initialize the distances
    std::vector<std::vector<int>> distances(
    g.height(), std::vector(g.width(), graph::unreachable()));

    // initialize the visited
    std::vector<std::vector<bool>> visited(g.height(),
    std::vector(g.width(), false));

    // ‹source› destination denotes the beginning where the cost is 0
    auto [sx, sy] = source;
    distances[sy][sx] = 0;

    pqueue_t priority_queue{std::make_pair(0, source)};
    std::optional<pqueue_item_t> item{};
    while ((item = popq(priority_queue))) {
    auto [cost, u] = *item;
    auto [x, y] = u;

    // we have already found the shortest path
    if (visited[y][x]) {
    continue;
    }
    visited[y][x] = true;

    for (const auto& [dx, dy] : DIRECTIONS) {
    auto v = std::make_pair(x + dx, y + dy);
    auto cost = g.cost(u, v);

    // if we can move to the cell and it's better, relax¹ it and update queue
    if (cost != graph::unreachable() &&
    distances[y][x] + cost < distances[y + dy][x + dx]) {
    distances[y + dy][x + dx] = distances[y][x] + cost;
    pushq(priority_queue, std::make_pair(distances[y + dy][x + dx], v));
    }
    }
    }

    return distances;
    }

    Time complexity

    The time complexity of Dijkstra's algorithm differs based on the backing data structure.

    @@ -115,7 +115,7 @@ insertion and Running the Dijkstra

    Let's run our code:

    -
    Normal cost: 1
    Vortex cost: 5
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    [Finite BF] Cost: 22
    [Bellman-Ford] Cost: 22
    [Dijkstra] Cost: 22
    +
    Normal cost: 1
    Vortex cost: 5
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    [Finite BF] Cost: 22
    [Bellman-Ford] Cost: 22
    [Dijkstra] Cost: 22

    OK, so it seems to be working just fine. Now the question arises:

    What happens when we have negative weights in our graph?

    @@ -126,7 +126,7 @@ infinitely when you have negative weights or loops in the graph. Well, if we use our propelling vortices, not only we have the negative weights, but also the negative loops. Let's run our code! Our first naïve approach was actually looping:

    -
    Normal cost: 1
    Vortex cost: -1
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    [Finite BF] Cost: -240
    [Bellman-Ford] Found a negative loop
    [Bellman-Ford] Cost: -240
    [Dijkstra] Cost: 14
    +
    Normal cost: 1
    Vortex cost: -1
    Graph:
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #D...#....#.#
    ########*.*.#
    #S..........#
    #############
    [Finite BF] Cost: -240
    [Bellman-Ford] Found a negative loop
    [Bellman-Ford] Cost: -240
    [Dijkstra] Cost: 14

    Well, it definitely doesn't loop. How much does 14 make sense is a different matter.

    Variations

    There are multiple variations of the Dijkstra's algorithm. You can implement diff --git a/algorithms/paths/bf-to-astar/index.html b/algorithms/paths/bf-to-astar/index.html index 013cf61..7726158 100644 --- a/algorithms/paths/bf-to-astar/index.html +++ b/algorithms/paths/bf-to-astar/index.html @@ -16,8 +16,8 @@ - - + +

    From BF to A*

    Intro

    @@ -26,7 +26,7 @@ algorithms. For the purpose of demonstrating some “features” of the improved algorithms, we will use a 2D map with some rules that will allow us to show cons and pros of the shown algorithms.

    Let's have a look at the example map:

    -
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #....#....#.#
    ########*.*.#
    #...........#
    #############
    +
    #############
    #..#..*.*.**#
    ##***.....**#
    #..########.#
    #...###...#.#
    #..#...##.#.#
    #..#.*.#..#.#
    #....#....#.#
    ########*.*.#
    #...........#
    #############

    We can see three different kinds of cells:

    1. # which represent walls, that cannot be entered at all
    2. @@ -35,7 +35,7 @@ and pros of the shown algorithms.

      base price of moving around the map)

    Let's dissect a specific position on the map to get a better grasp of the rules:

    -
     .
    #S*
    .
    +
     .
    #S*
    .

    We are standing in the cell marked with S and we have the following options

    • move to the north (.) with the cost of 1 coin,
    • @@ -56,7 +56,7 @@ two positions on the map made

    We can see the graph header here:

    -
    #ifndef _GRAPH_HPP
    #define _GRAPH_HPP

    #include <cmath>
    #include <limits>
    #include <ostream>
    #include <utility>
    #include <vector>

    using vertex_t = std::pair<int, int>;

    struct graph {
    graph(const std::vector<std::vector<char>>& map)
    : map(map),
    _height(static_cast<int>(map.size())),
    _width(map.empty() ? 0 : static_cast<int>(map[0].size())) {}

    static auto unreachable() -> int { return UNREACHABLE; }
    static auto normal_cost() -> int { return NORMAL_COST; }
    static auto vortex_cost() -> int { return VORTEX_COST; }

    auto cost(const vertex_t& u, const vertex_t& v) const -> int {
    auto [ux, uy] = u;
    auto [vx, vy] = v;

    auto md = std::abs(ux - vx) + std::abs(uy - vy);
    switch (md) {
    // ‹u = v›; staying on the same cell
    case 0:
    return 0;
    // ‹u› and ‹v› are neighbours
    case 1:
    break;
    // ‹u› and ‹v› are not neighbouring cells
    default:
    return UNREACHABLE;
    }

    // boundary check
    if (vy < 0 || vy >= _height || vx < 0 || vx >= _width) {
    return UNREACHABLE;
    }

    switch (map[vy][vx]) {
    case '#':
    return UNREACHABLE;
    case '*':
    return VORTEX_COST;
    default:
    return NORMAL_COST;
    }
    }

    auto width() const -> int { return _width; }
    auto height() const -> int { return _height; }
    auto has(const vertex_t& v) const -> bool {
    auto [x, y] = v;
    return (0 <= y && y < _height) && (0 <= x && x < _width);
    }

    friend std::ostream& operator<<(std::ostream& os, const graph& g);

    private:
    std::vector<std::vector<char>> map;
    int _height, _width;

    const static int UNREACHABLE = std::numeric_limits<int>::max();
    // XXX: modify here to change the price of entering the vortex
    const static int VORTEX_COST = 5;
    const static int NORMAL_COST = 1;
    };

    std::ostream& operator<<(std::ostream& os, const graph& g) {
    for (const auto& row : g.map) {
    for (const char cell : row) {
    os << cell;
    }
    os << "\n";
    }

    return os;
    }

    #endif /* _GRAPH_HPP */
    +
    #ifndef _GRAPH_HPP
    #define _GRAPH_HPP

    #include <cmath>
    #include <limits>
    #include <ostream>
    #include <utility>
    #include <vector>

    using vertex_t = std::pair<int, int>;

    struct graph {
    graph(const std::vector<std::vector<char>>& map)
    : map(map),
    _height(static_cast<int>(map.size())),
    _width(map.empty() ? 0 : static_cast<int>(map[0].size())) {}

    static auto unreachable() -> int { return UNREACHABLE; }
    static auto normal_cost() -> int { return NORMAL_COST; }
    static auto vortex_cost() -> int { return VORTEX_COST; }

    auto cost(const vertex_t& u, const vertex_t& v) const -> int {
    auto [ux, uy] = u;
    auto [vx, vy] = v;

    auto md = std::abs(ux - vx) + std::abs(uy - vy);
    switch (md) {
    // ‹u = v›; staying on the same cell
    case 0:
    return 0;
    // ‹u› and ‹v› are neighbours
    case 1:
    break;
    // ‹u› and ‹v› are not neighbouring cells
    default:
    return UNREACHABLE;
    }

    // boundary check
    if (vy < 0 || vy >= _height || vx < 0 || vx >= _width) {
    return UNREACHABLE;
    }

    switch (map[vy][vx]) {
    case '#':
    return UNREACHABLE;
    case '*':
    return VORTEX_COST;
    default:
    return NORMAL_COST;
    }
    }

    auto width() const -> int { return _width; }
    auto height() const -> int { return _height; }
    auto has(const vertex_t& v) const -> bool {
    auto [x, y] = v;
    return (0 <= y && y < _height) && (0 <= x && x < _width);
    }

    friend std::ostream& operator<<(std::ostream& os, const graph& g);

    private:
    std::vector<std::vector<char>> map;
    int _height, _width;

    const static int UNREACHABLE = std::numeric_limits<int>::max();
    // XXX: modify here to change the price of entering the vortex
    const static int VORTEX_COST = 5;
    const static int NORMAL_COST = 1;
    };

    std::ostream& operator<<(std::ostream& os, const graph& g) {
    for (const auto& row : g.map) {
    for (const char cell : row) {
    os << cell;
    }
    os << "\n";
    }

    return os;
    }

    #endif /* _GRAPH_HPP */
    Source code

    You can find all the source code referenced in this series here.

    Let's finally start with some algorithms!

    diff --git a/algorithms/rb-trees/applications/index.html b/algorithms/rb-trees/applications/index.html index 6aaa4ba..eb24e7e 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í

    @@ -43,16 +43,16 @@ jsme vybrali několik jazyků.

    • map

      -
      template <class _Key, class _Tp, class _Compare = less<_Key>,
      class _Allocator = allocator<pair<const _Key, _Tp> > >
      class _LIBCPP_TEMPLATE_VIS map
      {
      public:
      // types:
      typedef _Key key_type;
      typedef _Tp mapped_type;
      typedef pair<const key_type, mapped_type> value_type;

      // …

      private:
      typedef __tree<__value_type, __vc, __allocator_type> __base;
      +
      template <class _Key, class _Tp, class _Compare = less<_Key>,
      class _Allocator = allocator<pair<const _Key, _Tp> > >
      class _LIBCPP_TEMPLATE_VIS map
      {
      public:
      // types:
      typedef _Key key_type;
      typedef _Tp mapped_type;
      typedef pair<const key_type, mapped_type> value_type;

      // …

      private:
      typedef __tree<__value_type, __vc, __allocator_type> __base;
    • set

      -
      template <class _Key, class _Compare = less<_Key>,
      class _Allocator = allocator<_Key> >
      class _LIBCPP_TEMPLATE_VIS set
      {
      public:
      // types:
      typedef _Key key_type;
      typedef key_type value_type;

      // …

      private:
      typedef __tree<value_type, value_compare, allocator_type> __base;
      +
      template <class _Key, class _Compare = less<_Key>,
      class _Allocator = allocator<_Key> >
      class _LIBCPP_TEMPLATE_VIS set
      {
      public:
      // types:
      typedef _Key key_type;
      typedef key_type value_type;

      // …

      private:
      typedef __tree<value_type, value_compare, allocator_type> __base;

    U obou hlaviček si můžeme všimnout, že deklarují nějaký soukromý typ __base, který je aliasem pro __tree. Ten nás pak vede k hlavičce __tree.

    Výňatek:

    -
    /*

    _NodePtr algorithms

    The algorithms taking _NodePtr are red black tree algorithms. Those
    algorithms taking a parameter named __root should assume that __root
    points to a proper red black tree (unless otherwise specified).



    */
    +
    /*

    _NodePtr algorithms

    The algorithms taking _NodePtr are red black tree algorithms. Those
    algorithms taking a parameter named __root should assume that __root
    points to a proper red black tree (unless otherwise specified).



    */

    gcc

    Pro gcc je postup téměř stejný. Pro změnu v hlavičkách map a set nenajdeme nic, deklarace jsou až v hlavičkových souborech:

    V obou se zase odkazuje na nějakou hlavičku bits/stl_tree.h, zase výňatek:

    -
      // Red-black tree class, designed for use in implementing STL
    // associative containers (set, multiset, map, and multimap). The
    // insertion and deletion algorithms are based on those in Cormen,
    // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
    // 1990), except that
    //
    // (1) the header cell is maintained with links not only to the root
    // but also to the leftmost node of the tree, to enable constant
    // time begin(), and to the rightmost node of the tree, to enable
    // linear time performance when used with the generic set algorithms
    // (set_union, etc.)
    //
    // (2) when a node being deleted has two children its successor node
    // is relinked into its place, rather than copied, so that the only
    // iterators invalidated are those referring to the deleted node.

    enum _Rb_tree_color { _S_red = false, _S_black = true };

    struct _Rb_tree_node_base
    {
    typedef _Rb_tree_node_base* _Base_ptr;
    typedef const _Rb_tree_node_base* _Const_Base_ptr;

    _Rb_tree_color _M_color;
    _Base_ptr _M_parent;
    _Base_ptr _M_left;
    _Base_ptr _M_right;

    static _Base_ptr
    _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
    {
    while (__x->_M_left != 0) __x = __x->_M_left;
    return __x;
    }

    static _Const_Base_ptr
    _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
    {
    while (__x->_M_left != 0) __x = __x->_M_left;
    return __x;
    }

    static _Base_ptr
    _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
    {
    while (__x->_M_right != 0) __x = __x->_M_right;
    return __x;
    }

    static _Const_Base_ptr
    _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
    {
    while (__x->_M_right != 0) __x = __x->_M_right;
    return __x;
    }
    +
      // Red-black tree class, designed for use in implementing STL
    // associative containers (set, multiset, map, and multimap). The
    // insertion and deletion algorithms are based on those in Cormen,
    // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
    // 1990), except that
    //
    // (1) the header cell is maintained with links not only to the root
    // but also to the leftmost node of the tree, to enable constant
    // time begin(), and to the rightmost node of the tree, to enable
    // linear time performance when used with the generic set algorithms
    // (set_union, etc.)
    //
    // (2) when a node being deleted has two children its successor node
    // is relinked into its place, rather than copied, so that the only
    // iterators invalidated are those referring to the deleted node.

    enum _Rb_tree_color { _S_red = false, _S_black = true };

    struct _Rb_tree_node_base
    {
    typedef _Rb_tree_node_base* _Base_ptr;
    typedef const _Rb_tree_node_base* _Const_Base_ptr;

    _Rb_tree_color _M_color;
    _Base_ptr _M_parent;
    _Base_ptr _M_left;
    _Base_ptr _M_right;

    static _Base_ptr
    _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
    {
    while (__x->_M_left != 0) __x = __x->_M_left;
    return __x;
    }

    static _Const_Base_ptr
    _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
    {
    while (__x->_M_left != 0) __x = __x->_M_left;
    return __x;
    }

    static _Base_ptr
    _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
    {
    while (__x->_M_right != 0) __x = __x->_M_right;
    return __x;
    }

    static _Const_Base_ptr
    _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
    {
    while (__x->_M_right != 0) __x = __x->_M_right;
    return __x;
    }

    Tady už taky vidíme nějaký kód pro nalezení minima/maxima ve stromě. Mimo jiné ještě existuje tree.cc, kde je lze nalézt třeba funkci s následující hlavičkou:

    -
    void
    _Rb_tree_insert_and_rebalance(const bool __insert_left,
    _Rb_tree_node_base* __x,
    _Rb_tree_node_base* __p,
    _Rb_tree_node_base& __header) throw ();
    +
    void
    _Rb_tree_insert_and_rebalance(const bool __insert_left,
    _Rb_tree_node_base* __x,
    _Rb_tree_node_base* __p,
    _Rb_tree_node_base& __header) throw ();

    Java

    V Javě jsou pro nás klíčové implementace TreeSet a TreeMap.

    V implementaci TreeSet si můžete povšimnout:

    -
    public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
    {
    /**
    * The backing map.
    */
    private transient NavigableMap<E,Object> m;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();
    +
    public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
    {
    /**
    * The backing map.
    */
    private transient NavigableMap<E,Object> m;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

    TreeSet v Javě tedy používá na pozadí TreeMap (což je vidět ve výchozím konstruktoru, kde se volá konstruktor přebírající NavigableMap<E, Object>, a je mu předáno new TreeMap<>()).

    Co se týče TreeMap, tak hned ze začátku definice TreeMap je vidět:

    -
    public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
    {
    /**
    * The comparator used to maintain order in this tree map, or
    * null if it uses the natural ordering of its keys.
    *
    * @serial
    */
    @SuppressWarnings("serial") // Conditionally serializable
    private final Comparator<? super K> comparator;

    private transient Entry<K,V> root;
    +
    public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
    {
    /**
    * The comparator used to maintain order in this tree map, or
    * null if it uses the natural ordering of its keys.
    *
    * @serial
    */
    @SuppressWarnings("serial") // Conditionally serializable
    private final Comparator<? super K> comparator;

    private transient Entry<K,V> root;

    Takže máme „nějaký kořen“ typu Entry<K,V>. Zkusíme si najít definici daného typu…

    -
        // Red-black mechanics

    private static final boolean RED = false;
    private static final boolean BLACK = true;

    /**
    * Node in the Tree. Doubles as a means to pass key-value pairs back to
    * user (see Map.Entry).
    */

    static final class Entry<K,V> implements Map.Entry<K,V> {
    K key;
    V value;
    Entry<K,V> left;
    Entry<K,V> right;
    Entry<K,V> parent;
    boolean color = BLACK;
    +
        // Red-black mechanics

    private static final boolean RED = false;
    private static final boolean BLACK = true;

    /**
    * Node in the Tree. Doubles as a means to pass key-value pairs back to
    * user (see Map.Entry).
    */

    static final class Entry<K,V> implements Map.Entry<K,V> {
    K key;
    V value;
    Entry<K,V> left;
    Entry<K,V> right;
    Entry<K,V> parent;
    boolean color = BLACK;

    A máme RB-tree.

    (Implementace vychází z projektu OpenJDK.)

    C#

    V C# se zaměříme na nejnovější vydání (.NET), které je open-source a podporováno i na operačních systémech založených na Linuxu.

    Nejdříve se podíváme na implementaci slovníku (SortedDictionary).

    -
        public class SortedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue> where TKey : notnull
    {
    [NonSerialized]
    private KeyCollection? _keys;
    [NonSerialized]
    private ValueCollection? _values;

    private readonly TreeSet<KeyValuePair<TKey, TValue>> _set; // Do not rename (binary serialization)
    +
        public class SortedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue> where TKey : notnull
    {
    [NonSerialized]
    private KeyCollection? _keys;
    [NonSerialized]
    private ValueCollection? _values;

    private readonly TreeSet<KeyValuePair<TKey, TValue>> _set; // Do not rename (binary serialization)

    Na první pohled máme problém, protože TreeSet není SortedSet, který by jsme čekali. Když se přesuneme na konec souboru, tak zjistíme, že TreeSet je jenom backward-compatible wrapper pro SortedSet.

    Přesuneme se k SortedSet. A hned ze začátku vidíme:

    -
        // A binary search tree is a red-black tree if it satisfies the following red-black properties:
    // 1. Every node is either red or black
    // 2. Every leaf (nil node) is black
    // 3. If a node is red, the both its children are black
    // 4. Every simple path from a node to a descendant leaf contains the same number of black nodes
    //
    // The basic idea of a red-black tree is to represent 2-3-4 trees as standard BSTs but to add one extra bit of information
    // per node to encode 3-nodes and 4-nodes.
    // 4-nodes will be represented as: B
    // R R
    //
    // 3 -node will be represented as: B or B
    // R B B R
    //
    // For a detailed description of the algorithm, take a look at "Algorithms" by Robert Sedgewick.

    internal enum NodeColor : byte
    {
    Black,
    Red
    }

    internal delegate bool TreeWalkPredicate<T>(SortedSet<T>.Node node);

    internal enum TreeRotation : byte
    {
    Left,
    LeftRight,
    Right,
    RightLeft
    }
    +
        // A binary search tree is a red-black tree if it satisfies the following red-black properties:
    // 1. Every node is either red or black
    // 2. Every leaf (nil node) is black
    // 3. If a node is red, the both its children are black
    // 4. Every simple path from a node to a descendant leaf contains the same number of black nodes
    //
    // The basic idea of a red-black tree is to represent 2-3-4 trees as standard BSTs but to add one extra bit of information
    // per node to encode 3-nodes and 4-nodes.
    // 4-nodes will be represented as: B
    // R R
    //
    // 3 -node will be represented as: B or B
    // R B B R
    //
    // For a detailed description of the algorithm, take a look at "Algorithms" by Robert Sedgewick.

    internal enum NodeColor : byte
    {
    Black,
    Red
    }

    internal delegate bool TreeWalkPredicate<T>(SortedSet<T>.Node node);

    internal enum TreeRotation : byte
    {
    Left,
    LeftRight,
    Right,
    RightLeft
    }

    Vysvětlení v komentáři trochu předbíhá náplň cvičení zaměřeného na B-stromy ;)

    Vztah mezi množinou a mapou

    Při každé implementaci ve standardní knihovně jsme si mohli všimnout, že strom implementuje vždy jenom jeden typ:

    JazykZpůsob implementace
    C++mapa ukládá dvojice do množiny
    Javamnožina ukládá prvky s „dummy“ hodnotou do mapy
    C#mapa ukládá dvojice do množiny

    Mapa vyžaduje, aby každý klíč měl přiřazenou právě jednu hodnotu, tedy klíče jsou navzájem mezi sebou unikátní. To nám umožňuje organizovat klíče do množiny, zde ale narazíme na nepříjemný problém spočívající v tom, že musíme do množiny vkladat dvojice prvků: (key, value). Tenhle přístup má ale zásadní problém:

    -
    # let's represent dictionary/map as a set
    set_of_values = set()

    # let's insert few pairs
    set_of_values.add((1, 2))
    set_of_values.add((0, 42))

    # let's set key 1 to value 6
    set_of_values.add((1, 6))

    set_of_values
    +
    # let's represent dictionary/map as a set
    set_of_values = set()

    # let's insert few pairs
    set_of_values.add((1, 2))
    set_of_values.add((0, 42))

    # let's set key 1 to value 6
    set_of_values.add((1, 6))

    set_of_values

    A dostaneme:

    -
    {(1, 6), (1, 2), (0, 42)}
    +
    {(1, 6), (1, 2), (0, 42)}

    V jednotlivých implementacích, které jste mohli vidět výše, se využívá nasledující, když:

    • mapa ukládá dvojice do množiny: Dvojice je obalená v samostatním typu, který porovnává jenom klíče
    • diff --git a/algorithms/rb-trees/rules/index.html b/algorithms/rb-trees/rules/index.html index c96fc73..7d63172 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

      @@ -88,7 +88,7 @@ different tree, so we keep this note in just as a “hack”.

      This rule might seem like a very important one, but overall is not. You can safely omit this rule, but you also need to deal with the consequences.

      Let's refresh our memory with the algorithm of insert fixup:

      -
      WHILE z.p.color == Red
      IF z.p == z.p.p.left
      y = z.p.p.right

      IF y.color == Red
      z.p.color = Black
      y.color = Black
      z.p.p.color = Red
      z = z.p.p
      ELSE
      IF z == z.p.right
      z = z.p
      Left-Rotate(T, z)
      z.p.color = Black
      z.p.p.color = Red
      Right-Rotate(T, z.p.p)
      ELSE (same as above with “right” and “left” exchanged)

      T.root.color = Black
      +
      WHILE z.p.color == Red
      IF z.p == z.p.p.left
      y = z.p.p.right

      IF y.color == Red
      z.p.color = Black
      y.color = Black
      z.p.p.color = Red
      z = z.p.p
      ELSE
      IF z == z.p.right
      z = z.p
      Left-Rotate(T, z)
      z.p.color = Black
      z.p.p.color = Red
      Right-Rotate(T, z.p.p)
      ELSE (same as above with “right” and “left” exchanged)

      T.root.color = Black
      tip

      If you have tried to implement any of the more complex data structures, such as red-black trees, etc., in a statically typed language that also checks you for NULL-correctness (e.g. mypy or even C# with nullable reference types), you diff --git a/algorithms/recursion/karel/index.html b/algorithms/recursion/karel/index.html index efad64f..505d0d0 100644 --- a/algorithms/recursion/karel/index.html +++ b/algorithms/recursion/karel/index.html @@ -16,8 +16,8 @@ - - + +

      Recursion and backtracking with Robot Karel

        @@ -149,7 +149,7 @@ majority of Python installations)
      • skeleton.py - skeleton for your solution, needs to be put in the same directory as karel_tk.py and takes path to the world as a first argument, example usage:

        -
        $ python3 skeleton.py stairs.kw
        +
        $ python3 skeleton.py stairs.kw
        • of course, this file can be renamed ;)
        diff --git a/algorithms/recursion/karel/solution/index.html b/algorithms/recursion/karel/solution/index.html index fd3d00d..c67be30 100644 --- a/algorithms/recursion/karel/solution/index.html +++ b/algorithms/recursion/karel/solution/index.html @@ -16,8 +16,8 @@ - - + +
      • »Rough« pseudocode

        We should be able to construct a skeleton of our solution at least. Pseudocode follows:

        -
        def find_exit
        if found the exit then
        signal others
        terminate
        end

        check left
        check front
        check right
        end
        +
        def find_exit
        if found the exit then
        signal others
        terminate
        end

        check left
        check front
        check right
        end

        As you can see, we only mention what we want to do very roughly, technical details are left out, except for the early return (which is the base of our recursive function).

        @@ -64,7 +64,7 @@ recursive function).

        In the proper pseudocode we will need to dive into the technical details like the way we check for exit, move around, etc.

        We can start by cleaning up and decomposing the function written above:

        -
        def find_exit
        # BASE: found exit
        if found_exit() then
        return true
        end

        # check left
        if left_is_clear() then
        turn_left()
        step()
        if find_exit() then
        return true
        end

        turn_around()
        step()
        turn_left()
        end

        # check front
        if front_is_clear() then
        step()
        if find_exit() then
        return true
        end

        turn_around()
        step()
        turn_around()
        end

        # check right
        if right_is_clear() then
        turn_right()
        step()
        if find_exit() then
        return true
        end

        turn_around()
        step()
        turn_right()
        end

        return false
        end
        +
        def find_exit
        # BASE: found exit
        if found_exit() then
        return true
        end

        # check left
        if left_is_clear() then
        turn_left()
        step()
        if find_exit() then
        return true
        end

        turn_around()
        step()
        turn_left()
        end

        # check front
        if front_is_clear() then
        step()
        if find_exit() then
        return true
        end

        turn_around()
        step()
        turn_around()
        end

        # check right
        if right_is_clear() then
        turn_right()
        step()
        if find_exit() then
        return true
        end

        turn_around()
        step()
        turn_right()
        end

        return false
        end

        We are missing few of the functions that we use in our pseudocode above:

        • found_exit()
        • @@ -72,20 +72,20 @@ the way we check for exit, move around, etc.

        • turn_right()

        We can implement those easily:

        -
        def found_exit
        if not beepers_present() then
        return false
        end

        pick_beeper()
        if beepers_present() then
        put_beeper()
        return false
        end

        put_beeper()
        return true
        end

        def turn_around
        turn_left()
        turn_left()
        end

        def turn_right
        turn_around()
        turn_left()
        end
        +
        def found_exit
        if not beepers_present() then
        return false
        end

        pick_beeper()
        if beepers_present() then
        put_beeper()
        return false
        end

        put_beeper()
        return true
        end

        def turn_around
        turn_left()
        turn_left()
        end

        def turn_right
        turn_around()
        turn_left()
        end

        Now we have everything ready for implementing it in Python.

        Actual implementation

        It's just a matter of rewriting the pseudocode into Python1:

        -
        class SuperKarel(Karel):
        # you can define your own helper functions on Karel here, if you wish to

        def found_exit(self) -> bool:
        if not self.beepers_present():
        return False

        self.pick_beeper()
        if self.beepers_present():
        self.put_beeper()
        return False

        self.put_beeper()
        return True

        def turn_around(self):
        for _ in range(2):
        self.turn_left()

        def turn_right(self):
        for _ in range(3):
        self.turn_left()

        def find_exit(self) -> bool:
        if self.found_exit():
        return True

        # check left
        if self.left_is_clear():
        self.turn_left()
        self.step()
        if self.find_exit():
        return True

        self.turn_around()
        self.step()
        self.turn_left()

        # check front
        if self.front_is_clear():
        self.step()
        if self.find_exit():
        return True

        self.turn_around()
        self.step()
        self.turn_around()

        # check right
        if self.right_is_clear():
        self.turn_right()
        self.step()
        if self.find_exit():
        return True

        self.turn_around()
        self.step()
        self.turn_right()

        return False

        def run(self):
        self.find_exit()
        +
        class SuperKarel(Karel):
        # you can define your own helper functions on Karel here, if you wish to

        def found_exit(self) -> bool:
        if not self.beepers_present():
        return False

        self.pick_beeper()
        if self.beepers_present():
        self.put_beeper()
        return False

        self.put_beeper()
        return True

        def turn_around(self):
        for _ in range(2):
        self.turn_left()

        def turn_right(self):
        for _ in range(3):
        self.turn_left()

        def find_exit(self) -> bool:
        if self.found_exit():
        return True

        # check left
        if self.left_is_clear():
        self.turn_left()
        self.step()
        if self.find_exit():
        return True

        self.turn_around()
        self.step()
        self.turn_left()

        # check front
        if self.front_is_clear():
        self.step()
        if self.find_exit():
        return True

        self.turn_around()
        self.step()
        self.turn_around()

        # check right
        if self.right_is_clear():
        self.turn_right()
        self.step()
        if self.find_exit():
        return True

        self.turn_around()
        self.step()
        self.turn_right()

        return False

        def run(self):
        self.find_exit()

        We have relatively repetitive code for checking each of the directions, I would propose to refactor a bit, in a fashion of checkin just forward, so it's more readable:

        -
        def find_exit(self) -> bool:
        if self.found_exit():
        return True

        self.turn_left()
        for _ in range(3):
        if self.front_is_blocked():
        self.turn_right()
        continue

        self.step()
        if self.find_exit():
        return True

        self.step()
        self.turn_around()
        self.turn_right()

        return False
        +
        def find_exit(self) -> bool:
        if self.found_exit():
        return True

        self.turn_left()
        for _ in range(3):
        if self.front_is_blocked():
        self.turn_right()
        continue

        self.step()
        if self.find_exit():
        return True

        self.step()
        self.turn_around()
        self.turn_right()

        return False

        We can also notice that turning around takes 2 left turns and turning to right does 3. We get 5 left turns in total when we turn around and right afterwards… Taking 4 left turns just rotates us back to our initial direction, therefore it is sufficient to do just one left turn (5 % 4 == 1). That way we get:

        -
        def find_exit(self) -> bool:
        if self.found_exit():
        return True

        self.turn_left()
        for _ in range(3):
        if self.front_is_blocked():
        self.turn_right()
        continue

        self.step()
        if self.find_exit():
        return True

        self.step()
        # turning around and right is same as one turn to the left
        self.turn_left()

        return False
        +
        def find_exit(self) -> bool:
        if self.found_exit():
        return True

        self.turn_left()
        for _ in range(3):
        if self.front_is_blocked():
        self.turn_right()
        continue

        self.step()
        if self.find_exit():
        return True

        self.step()
        # turning around and right is same as one turn to the left
        self.turn_left()

        return False

        Testing

        In the skeleton, with the previous post, I have included multiple mazes that can be tested. I have tried this solution with all of the given mazes, and it was @@ -93,10 +93,10 @@ successful in finding the exit. However there is one precondition of our solution that we haven't spoken about.

        We are silently expecting the maze not to have any loops. Example of such maze can be the maze666.kw:

        -
        ┌─────────┬─┐
        │. . . . .│.│
        │ ┌─────┐ │ │
        │.│. . .│.│.│
        │ │ │ │ │ │
        │.│.│. . .│.│
        │ │ │ └─┤
        │.│.│. . . 1│
        │ │ │ │ ┌─┤
        │.│. . .│.│.│
        │ └─────┘ │ │
        │. > . . .│.│
        └─────────┴─┘
        +
        ┌─────────┬─┐
        │. . . . .│.│
        │ ┌─────┐ │ │
        │.│. . .│.│.│
        │ │ │ │ │ │
        │.│.│. . .│.│
        │ │ │ └─┤
        │.│.│. . . 1│
        │ │ │ │ ┌─┤
        │.│. . .│.│.│
        │ └─────┘ │ │
        │. > . . .│.│
        └─────────┴─┘

        If you try running our solution on this map, Karel just loops and never finds the solution. Let's have a look at the loop he gets stuck in:

        -
        ┌─────────┬─┐
        │* * * * *│.│
        │ ┌─────┐ │ │
        │*│* * *│*│.│
        │ │ │ │ │ │
        │*│*│. * *│.│
        │ │ │ └─┤
        │*│*│. * * 1│
        │ │ │ │ ┌─┤
        │*│* * *│*│.│
        │ └─────┘ │ │
        │* * * * *│.│
        └─────────┴─┘
        +
        ┌─────────┬─┐
        │* * * * *│.│
        │ ┌─────┐ │ │
        │*│* * *│*│.│
        │ │ │ │ │ │
        │*│*│. * *│.│
        │ │ │ └─┤
        │*│*│. * * 1│
        │ │ │ │ ┌─┤
        │*│* * *│*│.│
        │ └─────┘ │ │
        │* * * * *│.│
        └─────────┴─┘

        He walks past the exit, but can't see it, cause there's always a feasible path that is worth trying.

        Algorithm

        The algorithm we have written to find the exit is a depth-first search (DFS). @@ -107,7 +107,7 @@ are being (or have already been) explored.

        to mark the “cells” that we have tried. We can easily use beepers for this, but we need to be careful not to confuse the exit with already visited cell.

        To do that we'll use 2 beepers instead of the one. Implementation follows:

        -
        def visited(self) -> bool:
        if not self.beepers_present():
        return False

        self.pick_beeper()
        if not self.beepers_present():
        self.put_beeper()
        return False

        self.pick_beeper()
        if self.beepers_present():
        assert False, "no cell shall be marked with 3 beepers"

        self.put_beeper()
        self.put_beeper()
        return True


        def find_exit(self) -> bool:
        # BASE: already tried
        if self.visited():
        self.turn_around()
        return False

        # BASE
        if self.found_exit():
        return True

        # mark the cell as visited
        for _ in range(2):
        self.put_beeper()

        self.turn_left()
        for _ in range(3):
        if self.front_is_blocked():
        self.turn_right()
        continue

        self.step()
        if self.find_exit():
        return True

        self.step()
        # turning around and right is same as one turn to the left
        self.turn_left()

        return False
        +
        def visited(self) -> bool:
        if not self.beepers_present():
        return False

        self.pick_beeper()
        if not self.beepers_present():
        self.put_beeper()
        return False

        self.pick_beeper()
        if self.beepers_present():
        assert False, "no cell shall be marked with 3 beepers"

        self.put_beeper()
        self.put_beeper()
        return True


        def find_exit(self) -> bool:
        # BASE: already tried
        if self.visited():
        self.turn_around()
        return False

        # BASE
        if self.found_exit():
        return True

        # mark the cell as visited
        for _ in range(2):
        self.put_beeper()

        self.turn_left()
        for _ in range(3):
        if self.front_is_blocked():
        self.turn_right()
        continue

        self.step()
        if self.find_exit():
        return True

        self.step()
        # turning around and right is same as one turn to the left
        self.turn_left()

        return False

        Now our solution works also for mazes that have loops.

        Footnotes

          diff --git a/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html b/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html index 7067c4b..9a1c4ee 100644 --- a/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html +++ b/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html @@ -16,8 +16,8 @@ - - + +

          Bottom-up dynamic programming

          @@ -30,7 +30,7 @@ DP (unless the cached function has complicated parameters, in that case it might get messy).

          Bottom-up dynamic programming can be more effective, but may be more complicated to implement right from the beginning.

          Let's see how we can implement it:

          -
          public static int longestSlideDown(int[][] pyramid) {
          // In the beginning we declare new array. At this point it is easier to just
          // work with the one dimension, i.e. just allocating the space for the rows.
          int[][] slideDowns = new int[pyramid.length][];

          // Bottom row gets just copied, there's nothing else to do… It's the base
          // case.
          slideDowns[pyramid.length - 1] = Arrays.copyOf(pyramid[pyramid.length - 1],
          pyramid[pyramid.length - 1].length);

          // Then we need to propagate the found slide downs for each of the levels
          // above.
          for (int y = pyramid.length - 2; y >= 0; --y) {
          // We start by copying the values lying in the row we're processing.
          // They get included in the final sum and we need to allocate the space
          // for the precalculated slide downs anyways.
          int[] row = Arrays.copyOf(pyramid[y], pyramid[y].length);

          // At this we just need to “fetch” the partial results from “neighbours”
          for (int x = 0; x < row.length; ++x) {
          // We look under our position, since we expect the rows to get
          // shorter, we can safely assume such position exists.
          int under = slideDowns[y + 1][x];

          // Then we have a look to the right, such position doesn't have to
          // exist, e.g. on the right edge, so we validate the index, and if
          // it doesn't exist, we just assign minimum of the ‹int› which makes
          // sure that it doesn't get picked in the ‹Math.max()› call.
          int toRight = x + 1 < slideDowns[y + 1].length
          ? slideDowns[y + 1][x + 1]
          : Integer.MIN_VALUE;

          // Finally we add the best choice at this point.
          row[x] += Math.max(under, toRight);
          }

          // And save the row we've just calculated partial results for to the
          // “table”.
          slideDowns[y] = row;
          }

          // At the end we can find our seeked slide down at the top cell.
          return slideDowns[0][0];
          }
          +
          public static int longestSlideDown(int[][] pyramid) {
          // In the beginning we declare new array. At this point it is easier to just
          // work with the one dimension, i.e. just allocating the space for the rows.
          int[][] slideDowns = new int[pyramid.length][];

          // Bottom row gets just copied, there's nothing else to do… It's the base
          // case.
          slideDowns[pyramid.length - 1] = Arrays.copyOf(pyramid[pyramid.length - 1],
          pyramid[pyramid.length - 1].length);

          // Then we need to propagate the found slide downs for each of the levels
          // above.
          for (int y = pyramid.length - 2; y >= 0; --y) {
          // We start by copying the values lying in the row we're processing.
          // They get included in the final sum and we need to allocate the space
          // for the precalculated slide downs anyways.
          int[] row = Arrays.copyOf(pyramid[y], pyramid[y].length);

          // At this we just need to “fetch” the partial results from “neighbours”
          for (int x = 0; x < row.length; ++x) {
          // We look under our position, since we expect the rows to get
          // shorter, we can safely assume such position exists.
          int under = slideDowns[y + 1][x];

          // Then we have a look to the right, such position doesn't have to
          // exist, e.g. on the right edge, so we validate the index, and if
          // it doesn't exist, we just assign minimum of the ‹int› which makes
          // sure that it doesn't get picked in the ‹Math.max()› call.
          int toRight = x + 1 < slideDowns[y + 1].length
          ? slideDowns[y + 1][x + 1]
          : Integer.MIN_VALUE;

          // Finally we add the best choice at this point.
          row[x] += Math.max(under, toRight);
          }

          // And save the row we've just calculated partial results for to the
          // “table”.
          slideDowns[y] = row;
          }

          // At the end we can find our seeked slide down at the top cell.
          return slideDowns[0][0];
          }

          I've tried to explain the code as much as possible within the comments, since it might be more beneficial to see right next to the “offending” lines.

          As you can see, in this approach we go from the other side1, the bottom of diff --git a/algorithms/recursion/pyramid-slide-down/greedy/index.html b/algorithms/recursion/pyramid-slide-down/greedy/index.html index b7a0c54..6dfd4ab 100644 --- a/algorithms/recursion/pyramid-slide-down/greedy/index.html +++ b/algorithms/recursion/pyramid-slide-down/greedy/index.html @@ -16,8 +16,8 @@ - - + +

          Greedy solution

          We will try to optimize it a bit. Let's start with a relatively simple greedy @@ -26,7 +26,7 @@ approach.

          optimal option at the moment.

          We can try to adjust the naïve solution. The most problematic part are the recursive calls. Let's apply the greedy approach there:

          -
          public static int longestSlideDown(int[][] pyramid, int row, int col) {
          if (row == pyramid.length - 1) {
          // BASE: We're at the bottom
          return pyramid[row][col];
          }

          if (col + 1 >= pyramid[row + 1].length
          || pyramid[row + 1][col] > pyramid[row + 1][col + 1]) {
          // If we cannot go right or it's not feasible, we continue to the left.
          return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col);
          }

          // Otherwise we just move to the right.
          return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col + 1);
          }
          +
          public static int longestSlideDown(int[][] pyramid, int row, int col) {
          if (row == pyramid.length - 1) {
          // BASE: We're at the bottom
          return pyramid[row][col];
          }

          if (col + 1 >= pyramid[row + 1].length
          || pyramid[row + 1][col] > pyramid[row + 1][col + 1]) {
          // If we cannot go right or it's not feasible, we continue to the left.
          return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col);
          }

          // Otherwise we just move to the right.
          return pyramid[row][col] + longestSlideDown(pyramid, row + 1, col + 1);
          }

          OK, if we cannot go right or the right path adds smaller value to the sum, we simply go left.

          Time complexity

          @@ -37,12 +37,12 @@ the way to the bottom. Therefore we are getting:

          We have managed to convert our exponential solution into a linear one.

          Running the tests

          However, if we run the tests, we notice that the second test failed:

          -
          Test #1: passed
          Test #2: failed
          +
          Test #1: passed
          Test #2: failed

          What's going on? Well, we have improved the time complexity, but greedy algorithms are not the ideal solution to all problems. In this case there may be a solution that is bigger than the one found using the greedy algorithm.

          Imagine the following pyramid:

          -
                1
          2 3
          5 6 7
          8 9 10 11
          99 13 14 15 16
          +
                1
          2 3
          5 6 7
          8 9 10 11
          99 13 14 15 16

          We start at the top:

          1. Current cell: 1, we can choose from 2 and 3, 3 looks better, so we diff --git a/algorithms/recursion/pyramid-slide-down/index.html b/algorithms/recursion/pyramid-slide-down/index.html index d264368..5ccbe3c 100644 --- a/algorithms/recursion/pyramid-slide-down/index.html +++ b/algorithms/recursion/pyramid-slide-down/index.html @@ -16,8 +16,8 @@ - - + +

            Introduction to dynamic programming

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

            @@ -27,12 +27,12 @@

            We are given a 2D array of integers and we are to find the slide down. Slide down is a maximum sum of consecutive numbers from the top to the bottom.

            Let's have a look at few examples. Consider the following pyramid:

            -
               3
            7 4
            2 4 6
            8 5 9 3
            +
               3
            7 4
            2 4 6
            8 5 9 3

            This pyramid has following slide down:

            -
               *3
            *7 4
            2 *4 6
            8 5 *9 3
            +
               *3
            *7 4
            2 *4 6
            8 5 *9 3

            And its value is 23.

            We can also have a look at a bigger example:

            -
                            75
            95 64
            17 47 82
            18 35 87 10
            20 4 82 47 65
            19 1 23 3 34
            88 2 77 73 7 63 67
            99 65 4 28 6 16 70 92
            41 41 26 56 83 40 80 70 33
            41 48 72 33 47 32 37 16 94 29
            53 71 44 65 25 43 91 52 97 51 14
            70 11 33 28 77 73 17 78 39 68 17 57
            91 71 52 38 17 14 91 43 58 50 27 29 48
            63 66 4 68 89 53 67 30 73 16 69 87 40 31
            4 62 98 27 23 9 70 98 73 93 38 53 60 4 23
            +
                            75
            95 64
            17 47 82
            18 35 87 10
            20 4 82 47 65
            19 1 23 3 34
            88 2 77 73 7 63 67
            99 65 4 28 6 16 70 92
            41 41 26 56 83 40 80 70 33
            41 48 72 33 47 32 37 16 94 29
            53 71 44 65 25 43 91 52 97 51 14
            70 11 33 28 77 73 17 78 39 68 17 57
            91 71 52 38 17 14 91 43 58 50 27 29 48
            63 66 4 68 89 53 67 30 73 16 69 87 40 31
            4 62 98 27 23 9 70 98 73 93 38 53 60 4 23

            Slide down in this case is equal to 1074.

            Solving the problem

            caution

            I will describe the following ways you can approach this problem and implement @@ -41,7 +41,7 @@ them in Javatrue/false based on the expected output of our algorithm. Any other differences will lie only in the solutions of the problem. You can see the main here:

            -
            public static void main(String[] args) {
            System.out.print("Test #1: ");
            System.out.println(longestSlideDown(new int[][] {
            { 3 },
            { 7, 4 },
            { 2, 4, 6 },
            { 8, 5, 9, 3 }
            }) == 23 ? "passed" : "failed");

            System.out.print("Test #2: ");
            System.out.println(longestSlideDown(new int[][] {
            { 75 },
            { 95, 64 },
            { 17, 47, 82 },
            { 18, 35, 87, 10 },
            { 20, 4, 82, 47, 65 },
            { 19, 1, 23, 75, 3, 34 },
            { 88, 2, 77, 73, 7, 63, 67 },
            { 99, 65, 4, 28, 6, 16, 70, 92 },
            { 41, 41, 26, 56, 83, 40, 80, 70, 33 },
            { 41, 48, 72, 33, 47, 32, 37, 16, 94, 29 },
            { 53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14 },
            { 70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57 },
            { 91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48 },
            { 63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31 },
            { 4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23 },
            }) == 1074 ? "passed" : "failed");
            }
            +
            public static void main(String[] args) {
            System.out.print("Test #1: ");
            System.out.println(longestSlideDown(new int[][] {
            { 3 },
            { 7, 4 },
            { 2, 4, 6 },
            { 8, 5, 9, 3 }
            }) == 23 ? "passed" : "failed");

            System.out.print("Test #2: ");
            System.out.println(longestSlideDown(new int[][] {
            { 75 },
            { 95, 64 },
            { 17, 47, 82 },
            { 18, 35, 87, 10 },
            { 20, 4, 82, 47, 65 },
            { 19, 1, 23, 75, 3, 34 },
            { 88, 2, 77, 73, 7, 63, 67 },
            { 99, 65, 4, 28, 6, 16, 70, 92 },
            { 41, 41, 26, 56, 83, 40, 80, 70, 33 },
            { 41, 48, 72, 33, 47, 32, 37, 16, 94, 29 },
            { 53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14 },
            { 70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57 },
            { 91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48 },
            { 63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31 },
            { 4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23 },
            }) == 1074 ? "passed" : "failed");
            }

            Footnotes

            1. diff --git a/algorithms/recursion/pyramid-slide-down/naive/index.html b/algorithms/recursion/pyramid-slide-down/naive/index.html index adafdeb..0b2326b 100644 --- a/algorithms/recursion/pyramid-slide-down/naive/index.html +++ b/algorithms/recursion/pyramid-slide-down/naive/index.html @@ -16,15 +16,15 @@ - - + +

              Naïve solution

              Our naïve solution consists of trying out all the possible slides and finding the one with maximum sum.

              -
              public static int longestSlideDown(int[][] pyramid, int row, int col) {
              if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {
              // BASE: We have gotten out of bounds, there's no reasonable value to
              // return, so we just return the ‹MIN_VALUE› to ensure that it cannot
              // be maximum.
              return Integer.MIN_VALUE;
              }

              if (row == pyramid.length - 1) {
              // BASE: Bottom of the pyramid, we just return the value, there's
              // nowhere to slide anymore.
              return pyramid[row][col];
              }

              // Otherwise we account for the current position and return maximum of the
              // available “slides”.
              return pyramid[row][col] + Math.max(
              longestSlideDown(pyramid, row + 1, col),
              longestSlideDown(pyramid, row + 1, col + 1));
              }

              public static int longestSlideDown(int[][] pyramid) {
              // We start the slide in the top cell of the pyramid.
              return longestSlideDown(pyramid, 0, 0);
              }
              +
              public static int longestSlideDown(int[][] pyramid, int row, int col) {
              if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {
              // BASE: We have gotten out of bounds, there's no reasonable value to
              // return, so we just return the ‹MIN_VALUE› to ensure that it cannot
              // be maximum.
              return Integer.MIN_VALUE;
              }

              if (row == pyramid.length - 1) {
              // BASE: Bottom of the pyramid, we just return the value, there's
              // nowhere to slide anymore.
              return pyramid[row][col];
              }

              // Otherwise we account for the current position and return maximum of the
              // available “slides”.
              return pyramid[row][col] + Math.max(
              longestSlideDown(pyramid, row + 1, col),
              longestSlideDown(pyramid, row + 1, col + 1));
              }

              public static int longestSlideDown(int[][] pyramid) {
              // We start the slide in the top cell of the pyramid.
              return longestSlideDown(pyramid, 0, 0);
              }

              As you can see, we have 2 overloads:

              -
              int longestSlideDown(int[][] pyramid);
              int longestSlideDown(int[][] pyramid, int row, int col);
              +
              int longestSlideDown(int[][] pyramid);
              int longestSlideDown(int[][] pyramid, int row, int col);

              First one is used as a public interface to the solution, you just pass in the pyramid itself. Second one is the recursive “algorithm” that finds the slide down.

              @@ -37,12 +37,12 @@ are wondering about the time complexity of the proposed solution and, since it really is a naïve solution, the time complexity is pretty bad. Let's find the worst case scenario.

              Let's start with the first overload:

              -
              public static int longestSlideDown(int[][] pyramid) {
              return longestSlideDown(pyramid, 0, 0);
              }
              +
              public static int longestSlideDown(int[][] pyramid) {
              return longestSlideDown(pyramid, 0, 0);
              }

              There's not much to do here, so we can safely say that the time complexity of this function is bounded by T(n)T(n), where TT is our second overload. This doesn't tell us anything, so let's move on to the second overload where we are going to define the T(n)T(n) function.

              -
              public static int longestSlideDown(int[][] pyramid, int row, int col) {
              if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {
              // BASE: We have gotten out of bounds, there's no reasonable value to
              // return, so we just return the ‹MIN_VALUE› to ensure that it cannot
              // be maximum.
              return Integer.MIN_VALUE;
              }

              if (row == pyramid.length - 1) {
              // BASE: Bottom of the pyramid, we just return the value, there's
              // nowhere to slide anymore.
              return pyramid[row][col];
              }

              // Otherwise we account for the current position and return maximum of the
              // available “slides”.
              return pyramid[row][col] + Math.max(
              longestSlideDown(pyramid, row + 1, col),
              longestSlideDown(pyramid, row + 1, col + 1));
              }
              +
              public static int longestSlideDown(int[][] pyramid, int row, int col) {
              if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {
              // BASE: We have gotten out of bounds, there's no reasonable value to
              // return, so we just return the ‹MIN_VALUE› to ensure that it cannot
              // be maximum.
              return Integer.MIN_VALUE;
              }

              if (row == pyramid.length - 1) {
              // BASE: Bottom of the pyramid, we just return the value, there's
              // nowhere to slide anymore.
              return pyramid[row][col];
              }

              // Otherwise we account for the current position and return maximum of the
              // available “slides”.
              return pyramid[row][col] + Math.max(
              longestSlideDown(pyramid, row + 1, col),
              longestSlideDown(pyramid, row + 1, col + 1));
              }

              Fun fact is that the whole “algorithm” consists of just 2 return statements and nothing else. Let's dissect them!

              First return statement is the base case, so it has a constant time complexity.

              diff --git a/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html b/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html index 2415276..5ce0067 100644 --- a/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html +++ b/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html @@ -16,8 +16,8 @@ - - + +

              Top-down dynamic programming

              @@ -26,7 +26,7 @@ least looks like) is the easiest to implement. The whole point is avoiding the unnecessary computations that we have already done.

              In our case, we can use our naïve solution and put a cache on top of it that will make sure, we don't do unnecessary calculations.

              -
              // This “structure” is required, since I have decided to use ‹TreeMap› which
              // requires the ordering on the keys. It represents one position in the pyramid.
              record Position(int row, int col) implements Comparable<Position> {
              public int compareTo(Position r) {
              if (row != r.row) {
              return Integer.valueOf(row).compareTo(r.row);
              }

              if (col != r.col) {
              return Integer.valueOf(col).compareTo(r.col);
              }

              return 0;
              }
              }

              public static int longestSlideDown(
              int[][] pyramid,
              TreeMap<Position, Integer> cache,
              Position position) {
              int row = position.row;
              int col = position.col;

              if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {
              // BASE: out of bounds
              return Integer.MIN_VALUE;
              }

              if (row == pyramid.length - 1) {
              // BASE: bottom of the pyramid
              return pyramid[position.row][position.col];
              }

              if (!cache.containsKey(position)) {
              // We haven't computed the position yet, so we run the same “formula” as
              // in the naïve version »and« we put calculated slide into the cache.
              // Next time we want the slide down from given position, it will be just
              // retrieved from the cache.
              int slideDown = Math.max(
              longestSlideDown(pyramid, cache, new Position(row + 1, col)),
              longestSlideDown(pyramid, cache, new Position(row + 1, col + 1)));
              cache.put(position, pyramid[row][col] + slideDown);
              }

              return cache.get(position);
              }

              public static int longestSlideDown(int[][] pyramid) {
              // At the beginning we need to create a cache and share it across the calls.
              TreeMap<Position, Integer> cache = new TreeMap<>();
              return longestSlideDown(pyramid, cache, new Position(0, 0));
              }
              +
              // This “structure” is required, since I have decided to use ‹TreeMap› which
              // requires the ordering on the keys. It represents one position in the pyramid.
              record Position(int row, int col) implements Comparable<Position> {
              public int compareTo(Position r) {
              if (row != r.row) {
              return Integer.valueOf(row).compareTo(r.row);
              }

              if (col != r.col) {
              return Integer.valueOf(col).compareTo(r.col);
              }

              return 0;
              }
              }

              public static int longestSlideDown(
              int[][] pyramid,
              TreeMap<Position, Integer> cache,
              Position position) {
              int row = position.row;
              int col = position.col;

              if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {
              // BASE: out of bounds
              return Integer.MIN_VALUE;
              }

              if (row == pyramid.length - 1) {
              // BASE: bottom of the pyramid
              return pyramid[position.row][position.col];
              }

              if (!cache.containsKey(position)) {
              // We haven't computed the position yet, so we run the same “formula” as
              // in the naïve version »and« we put calculated slide into the cache.
              // Next time we want the slide down from given position, it will be just
              // retrieved from the cache.
              int slideDown = Math.max(
              longestSlideDown(pyramid, cache, new Position(row + 1, col)),
              longestSlideDown(pyramid, cache, new Position(row + 1, col + 1)));
              cache.put(position, pyramid[row][col] + slideDown);
              }

              return cache.get(position);
              }

              public static int longestSlideDown(int[][] pyramid) {
              // At the beginning we need to create a cache and share it across the calls.
              TreeMap<Position, Integer> cache = new TreeMap<>();
              return longestSlideDown(pyramid, cache, new Position(0, 0));
              }

              You have probably noticed that record Position have appeared. Since we are caching the already computed values, we need a “reasonable” key. In this case we share the cache only for one run (i.e. pyramid) of the longestSlideDown, so @@ -60,7 +60,7 @@ the pyramid:

              is done only once.

              For each calculation we take 2 values from the cache and insert one value. Because we have chosen TreeMap, these 3 operations have logarithmic time -complexity and therefore this step is equivalent to 3log2n3 \cdot \log_2{n}.

              +complexity and therefore this step is equivalent to 3log2n3 \cdot \log_2{n}.

              However for the sake of simplicity, we are going to account only for the insertion, the reason is rather simple, if we include the 2 retrievals here, it will be interleaved with the next step, therefore it is easier to keep the diff --git a/algorithms/tags/a-star/index.html b/algorithms/tags/a-star/index.html index c1e11e5..14f2f07 100644 --- a/algorithms/tags/a-star/index.html +++ b/algorithms/tags/a-star/index.html @@ -14,8 +14,8 @@ - - + +

              One doc tagged with "a star"

              View All Tags

              From BF to A*

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

              One doc tagged with "applications"

              View All Tags

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

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

              One doc tagged with "astar"

              View All Tags

              A* algorithm

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

              2 docs tagged with "backtracking"

              View All Tags

              Recursion and backtracking with Robot Karel

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

              2 docs tagged with "balanced trees"

              View All Tags

              On the rules of the red-black tree

              Shower thoughts on the rules of the red-black tree. diff --git a/algorithms/tags/bellman-ford/index.html b/algorithms/tags/bellman-ford/index.html index 36490a0..7af733a 100644 --- a/algorithms/tags/bellman-ford/index.html +++ b/algorithms/tags/bellman-ford/index.html @@ -14,8 +14,8 @@ - - + +

              2 docs tagged with "bellman ford"

              View All Tags

              BF

              Solving the shortest path problem with a naïve approach that turns into diff --git a/algorithms/tags/bfs/index.html b/algorithms/tags/bfs/index.html index 445f0a3..3b2f9f4 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 8f9bad0..3ebd690 100644 --- a/algorithms/tags/bottom-up-dp/index.html +++ b/algorithms/tags/bottom-up-dp/index.html @@ -14,8 +14,8 @@ - - + +

              2 docs tagged with "bottom-up-dp"

              View All Tags

              Bottom-up DP solution

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

              2 docs tagged with "brute force"

              View All Tags

              BF

              Solving the shortest path problem with a naïve approach that turns into diff --git a/algorithms/tags/c/index.html b/algorithms/tags/c/index.html index 5ab3997..41f4215 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 d59f9e2..bce0d2c 100644 --- a/algorithms/tags/cpp/index.html +++ b/algorithms/tags/cpp/index.html @@ -14,8 +14,8 @@ - - + +

              7 docs tagged with "cpp"

              View All Tags

              A* algorithm

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

              One doc tagged with "csharp"

              View All Tags

              Iterative algorithms via iterators

              Iterative DFS using iterators. diff --git a/algorithms/tags/dijkstra/index.html b/algorithms/tags/dijkstra/index.html index 3984a65..5eca9b4 100644 --- a/algorithms/tags/dijkstra/index.html +++ b/algorithms/tags/dijkstra/index.html @@ -14,8 +14,8 @@ - - + +

              2 docs tagged with "dijkstra"

              View All Tags

              Dijkstra's algorithm

              Moving from Bellman-Ford into the Dijsktra's algorithm. diff --git a/algorithms/tags/dynamic-array/index.html b/algorithms/tags/dynamic-array/index.html index 20f9d3b..d56a761 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 aba0075..fb8a48b 100644 --- a/algorithms/tags/dynamic-programming/index.html +++ b/algorithms/tags/dynamic-programming/index.html @@ -14,8 +14,8 @@ - - + +

              7 docs tagged with "dynamic programming"

              View All Tags

              A* algorithm

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

              2 docs tagged with "exponential"

              View All Tags

              Introduction to dynamic programming

              Solving a problem in different ways. diff --git a/algorithms/tags/graphs/index.html b/algorithms/tags/graphs/index.html index 31e8b3e..eccb604 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 39da3f8..12766df 100644 --- a/algorithms/tags/greedy/index.html +++ b/algorithms/tags/greedy/index.html @@ -14,8 +14,8 @@ - - + +

              4 docs tagged with "greedy"

              View All Tags

              Dijkstra's algorithm

              Moving from Bellman-Ford into the Dijsktra's algorithm. diff --git a/algorithms/tags/hash-tables/index.html b/algorithms/tags/hash-tables/index.html index c28a4b6..ad6df9b 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 16708fb..4316834 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 db6d878..a1c5198 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 fb6bb64..a36022a 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 82dda72..29f53f1 100644 --- a/algorithms/tags/java/index.html +++ b/algorithms/tags/java/index.html @@ -14,8 +14,8 @@ - - + +

              5 docs tagged with "java"

              View All Tags

              Bottom-up DP solution

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

              2 docs tagged with "karel"

              View All Tags

              Recursion and backtracking with Robot Karel

              A problem with too many restrictions. diff --git a/algorithms/tags/postconditions/index.html b/algorithms/tags/postconditions/index.html index 1e2ffca..89f06f3 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 e70f482..1a7cbd4 100644 --- a/algorithms/tags/python/index.html +++ b/algorithms/tags/python/index.html @@ -14,8 +14,8 @@ - - + +

              7 docs tagged with "python"

              View All Tags

              Breaking Hash Table

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

              5 docs tagged with "recursion"

              View All Tags

              Introduction to dynamic programming

              Solving a problem in different ways. diff --git a/algorithms/tags/red-black-trees/index.html b/algorithms/tags/red-black-trees/index.html index 1930e5c..1ea634f 100644 --- a/algorithms/tags/red-black-trees/index.html +++ b/algorithms/tags/red-black-trees/index.html @@ -14,8 +14,8 @@ - - + +

              2 docs tagged with "red-black trees"

              View All Tags

              On the rules of the red-black tree

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

              One doc tagged with "solution"

              View All Tags

              Solution to the problem

              Solving the problem introduced in the previous post. diff --git a/algorithms/tags/sorting/index.html b/algorithms/tags/sorting/index.html index 7b7ea65..ad1f56c 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 72e8c4d..69a4f33 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 c432205..67d1996 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 8e31fec..d74b3ed 100644 --- a/algorithms/tags/top-down-dp/index.html +++ b/algorithms/tags/top-down-dp/index.html @@ -14,8 +14,8 @@ - - + +

              2 docs tagged with "top-down-dp"

              View All Tags

              Introduction to dynamic programming

              Solving a problem in different ways. diff --git a/algorithms/time-complexity/extend/index.html b/algorithms/time-complexity/extend/index.html index cc9e3d3..23e4ab2 100644 --- a/algorithms/time-complexity/extend/index.html +++ b/algorithms/time-complexity/extend/index.html @@ -16,8 +16,8 @@ - - + +

      Example #1

      Let us assume function that uses divide & conquer strategy to return indices at which we can find specific element in any list.

      -
      def recursive_find_in_list(
      values: List[Any], key: Any, lower: int, upper: int
      ) -> List[int]:
      if lower == upper:
      return [lower] if values[lower] == key else []

      indices = []
      mid = (lower + upper) // 2

      indices.extend(recursive_find_in_list(values, key, lower, mid))
      indices.extend(recursive_find_in_list(values, key, mid + 1, upper))

      return indices


      def find_in_list(values: List[Any], key: Any) -> List[int]:
      return recursive_find_in_list(values, key, 0, len(values) - 1)
      +
      def recursive_find_in_list(
      values: List[Any], key: Any, lower: int, upper: int
      ) -> List[int]:
      if lower == upper:
      return [lower] if values[lower] == key else []

      indices = []
      mid = (lower + upper) // 2

      indices.extend(recursive_find_in_list(values, key, lower, mid))
      indices.extend(recursive_find_in_list(values, key, mid + 1, upper))

      return indices


      def find_in_list(values: List[Any], key: Any) -> List[int]:
      return recursive_find_in_list(values, key, 0, len(values) - 1)

      This implementation works nicely, extend is linear (with the respect to the length of the list that is being appended).

      Let us try to dissect the way this function works on some specific input (that will be pushed to the extreme, just in case ;)

      find_in_list([1] * 5000, 1). What shall be the result of this? Since we have key = 1 and the list contains only 1s, we should get list of all indices.

      @@ -88,7 +88,7 @@ elements from b.

    For the sake of Algorithms and Data Structures I we consider APPEND operation, i.e. adding the element to the end of the list, to have time complexity O(1)\mathcal{O}(1) (amortized; which is out of the scope of IB002).

    If we have a look at the extend implementation in this dynamic array example:

    -
    void dynamic_array_extend(struct dynamic_array_t *arr, struct dynamic_array_t *src)
    {
    if (arr == NULL || src == NULL)
    {
    return;
    }

    for (size_t i = 0; i < src->count; i++)
    {
    dynamic_array_push_back(arr, dynamic_array_at(src, i));
    }
    }
    +
    void dynamic_array_extend(struct dynamic_array_t *arr, struct dynamic_array_t *src)
    {
    if (arr == NULL || src == NULL)
    {
    return;
    }

    for (size_t i = 0; i < src->count; i++)
    {
    dynamic_array_push_back(arr, dynamic_array_at(src, i));
    }
    }

    Apart from checking edge cases, we can notice that we run for-loop over the elements from the other array and add them one-by-one to the arr. Time complexity of this operation is time dependant on the src array.

    In this specific implementation, you could also resize the memory allocated for the array in one go and copy whole src array in one go. However even if you did so, it would be still dependant on the size of the src array. Cause you still need to copy count(src)elementSize(src)\texttt{count}(src) \cdot \texttt{elementSize}(src) bytes. From that we can assume that for specific instance of array the elementSize(src)\texttt{elementSize}(src) is fixed, therefore we consider it a constant. That way we are getting O(count(src))\mathcal{O}(\texttt{count}(src)) as a time complexity of our extend operation.

    diff --git a/assets/js/1535ede8.b272bba2.js b/assets/js/1535ede8.b272bba2.js new file mode 100644 index 0000000..d623174 --- /dev/null +++ b/assets/js/1535ede8.b272bba2.js @@ -0,0 +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:1707050925,formattedLastUpdatedAt:"Feb 4, 2024",frontMatter:{id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},sidebar:"autogeneratedBar",previous:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"},next:{title:"Practice Exams",permalink:"/c/category/practice-exams"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Project",id:"project",level:2},{value:"Summary of the gameplay",id:"summary-of-the-gameplay",level:3},{value:"Suggested workflow",id:"suggested-workflow",level:2},{value:"Tasks",id:"tasks",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/10.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you are given almost finished project - The Hangman Game. Your\ntask is to try the game, in case you find any bugs point them out and cover as\nmuch of the game as possible with tests."}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2 K\u20a1."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Item"}),(0,s.jsx)(n.th,{children:"Bonus"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Fixing bugs from failing tests"}),(0,s.jsx)(n.td,{children:"0.25"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"word_guessed"})}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Hidden bug"}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Extending tests, undetectable bugs or evil bug"}),(0,s.jsx)(n.td,{children:"0.37"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Refactor"}),(0,s.jsx)(n.td,{children:"0.38"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"project",children:"Project"}),"\n",(0,s.jsxs)(n.p,{children:["Project consists of 2 source files - ",(0,s.jsx)(n.code,{children:"hangman.c"})," and ",(0,s.jsx)(n.code,{children:"main.c"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main.c"})," is quite short and concise, there is nothing for you to do."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"hangman.c"})," contains implementation of the game. In case you feel lost, consult\nthe documentation in ",(0,s.jsx)(n.code,{children:"hangman.h"})," that represents an interface that can be used\nfor implementing the game."]}),"\n",(0,s.jsxs)(n.p,{children:["Apart from those sources this project is a bit more complicated. ",(0,s.jsx)(n.em,{children:"Game loop"})," is\nrealised via single encapsulated function that complicates the testing. Because\nof that, there are 2 kinds of tests:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Unit tests"})," - that are present in ",(0,s.jsx)(n.code,{children:"test_hangman.c"})," and can be run via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-unit\n"})}),"\n",(0,s.jsx)(n.p,{children:"They cover majorly functions that can be tested easily via testing framework."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Functional tests"})," - same as in ",(0,s.jsx)(n.code,{children:"seminar-08"})," and are focused on testing the\nprogram as whole. Basic smoke test is already included in ",(0,s.jsx)(n.code,{children:"usage"})," test case."]}),"\n",(0,s.jsx)(n.p,{children:"They can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-functional\n"})}),"\n",(0,s.jsxs)(n.p,{children:["When testing ",(0,s.jsx)(n.code,{children:"hangman"})," function (the game loop), it is suggested to create\nfunctional tests."]}),"\n",(0,s.jsx)(n.p,{children:"When submitting the files for review, please leave out functional tests that\nwere given as a part of the assignment, so that it is easier to navigate, I\nwill drag the common files myself. :)"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Whole test suite can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check\n"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"summary-of-the-gameplay",children:"Summary of the gameplay"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Secret word gets chosen from the file that's path is given as an argument."}),"\n",(0,s.jsx)(n.li,{children:"You get 8 guesses."}),"\n",(0,s.jsx)(n.li,{children:"Invalid characters don't count."}),"\n",(0,s.jsx)(n.li,{children:"Already guessed characters don't count, even if not included in the secret."}),"\n",(0,s.jsxs)(n.li,{children:["You can guess the whole word at once","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"If you get it right, you won, game ends."}),"\n",(0,s.jsx)(n.li,{children:"If you don't get it right, you get to see the secret, game ends."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"In case of end of input, game finishes via force."}),"\n",(0,s.jsx)(n.li,{children:"In case of invalid input, no guesses are subtracted, game carries on."}),"\n",(0,s.jsx)(n.li,{children:"Letters and words are not case sensitive."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"suggested-workflow",children:"Suggested workflow"}),"\n",(0,s.jsxs)(n.p,{children:["As we have talked about on the seminar, I suggest you to follow\n",(0,s.jsx)(n.em,{children:"Test-Driven Development"}),"\nin this case."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"TDD workflow",src:t(27420).Z+"",width:"2814",height:"1652"})}),"\n",(0,s.jsx)(n.p,{children:"In our current scenario we are already in the stage of refactoring and fixing the\nbugs. Therefore try to follow this succession of steps:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Try to reproduce the bug."}),"\n",(0,s.jsx)(n.li,{children:"Create a test that proves the presence of the bug."}),"\n",(0,s.jsx)(n.li,{children:"Fix the bug."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are submitting the bonus via GitLab, it is helpful to commit tests\nbefore commiting the fixes, so that it is apparent that the bug is manifested.\nExample of ",(0,s.jsx)(n.code,{children:"git log"})," (notice that the first line represents latest commit):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"feat: Implement fizz_buzzer\ntest: Add tests for fizz_buzzer\nfix: Fix NULL-check in print_name\ntest: Add test for NULL in print_name\n"})}),"\n",(0,s.jsx)(n.h2,{id:"tasks",children:"Tasks"}),"\n",(0,s.jsx)(n.p,{children:"As to your tasks, there are multiple things wrong in this project."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'There are 2 "bugs" that cannot be detected via tests, i.e. they are not bugs\nthat affect functionality of the game.'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["There is one evil bug in ",(0,s.jsx)(n.code,{children:"get_word"}),". It is not required to be fixed ;) Assign\nit the lowest priority."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"There are some tests failing. Please try to figure it out, so you have green\ntests for the rest :)"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["We have gotten a bug report for ",(0,s.jsx)(n.code,{children:"word_guessed"}),", all we got is"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["doesn't work when there are too many ",(0,s.jsx)(n.code,{children:"a"}),"s"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Please try to replicate the bug and create a tests, so we don't get any\nregression later on."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"One hidden bug :) Closely non-specified, we cannot reproduce it and we were\ndrunk while playing the game, so we don't remember a thing. :/"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Try to cover as much code via the tests as possible. We are not going to look\nat the metrics, but DRY is violated a lot, so as a last task try to remove as\nmuch of the duplicit code as possible."}),"\n",(0,s.jsx)(n.p,{children:"Tests should help you a lot in case there are some regressions."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["In case you wonder why there are always 3 same words in the file with words, it\nis because of the ",(0,s.jsx)(n.code,{children:"get_word"})," bug. It is not a bug that can be easily fixed, so\nit is a not requirement at all and you can still get all points for the bonus ;)"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Functional_testing",children:"Functional tests"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Smoke_testing_%28software%29",children:"Smoke test"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself",children:"DRY"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},27420:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/tdd_lifecycle-327ad9ee0ed8318ed11e19a28e02b2cc.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var s=t(67294);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1535ede8.cf110382.js b/assets/js/1535ede8.cf110382.js deleted file mode 100644 index 29a4c79..0000000 --- a/assets/js/1535ede8.cf110382.js +++ /dev/null @@ -1 +0,0 @@ -"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:1706528814,formattedLastUpdatedAt:"Jan 29, 2024",frontMatter:{id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},sidebar:"autogeneratedBar",previous:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"},next:{title:"Practice Exams",permalink:"/c/category/practice-exams"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Project",id:"project",level:2},{value:"Summary of the gameplay",id:"summary-of-the-gameplay",level:3},{value:"Suggested workflow",id:"suggested-workflow",level:2},{value:"Tasks",id:"tasks",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/10.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you are given almost finished project - The Hangman Game. Your\ntask is to try the game, in case you find any bugs point them out and cover as\nmuch of the game as possible with tests."}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2 K\u20a1."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Item"}),(0,s.jsx)(n.th,{children:"Bonus"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Fixing bugs from failing tests"}),(0,s.jsx)(n.td,{children:"0.25"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"word_guessed"})}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Hidden bug"}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Extending tests, undetectable bugs or evil bug"}),(0,s.jsx)(n.td,{children:"0.37"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Refactor"}),(0,s.jsx)(n.td,{children:"0.38"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"project",children:"Project"}),"\n",(0,s.jsxs)(n.p,{children:["Project consists of 2 source files - ",(0,s.jsx)(n.code,{children:"hangman.c"})," and ",(0,s.jsx)(n.code,{children:"main.c"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main.c"})," is quite short and concise, there is nothing for you to do."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"hangman.c"})," contains implementation of the game. In case you feel lost, consult\nthe documentation in ",(0,s.jsx)(n.code,{children:"hangman.h"})," that represents an interface that can be used\nfor implementing the game."]}),"\n",(0,s.jsxs)(n.p,{children:["Apart from those sources this project is a bit more complicated. ",(0,s.jsx)(n.em,{children:"Game loop"})," is\nrealised via single encapsulated function that complicates the testing. Because\nof that, there are 2 kinds of tests:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Unit tests"})," - that are present in ",(0,s.jsx)(n.code,{children:"test_hangman.c"})," and can be run via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-unit\n"})}),"\n",(0,s.jsx)(n.p,{children:"They cover majorly functions that can be tested easily via testing framework."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Functional tests"})," - same as in ",(0,s.jsx)(n.code,{children:"seminar-08"})," and are focused on testing the\nprogram as whole. Basic smoke test is already included in ",(0,s.jsx)(n.code,{children:"usage"})," test case."]}),"\n",(0,s.jsx)(n.p,{children:"They can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-functional\n"})}),"\n",(0,s.jsxs)(n.p,{children:["When testing ",(0,s.jsx)(n.code,{children:"hangman"})," function (the game loop), it is suggested to create\nfunctional tests."]}),"\n",(0,s.jsx)(n.p,{children:"When submitting the files for review, please leave out functional tests that\nwere given as a part of the assignment, so that it is easier to navigate, I\nwill drag the common files myself. :)"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Whole test suite can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check\n"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"summary-of-the-gameplay",children:"Summary of the gameplay"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Secret word gets chosen from the file that's path is given as an argument."}),"\n",(0,s.jsx)(n.li,{children:"You get 8 guesses."}),"\n",(0,s.jsx)(n.li,{children:"Invalid characters don't count."}),"\n",(0,s.jsx)(n.li,{children:"Already guessed characters don't count, even if not included in the secret."}),"\n",(0,s.jsxs)(n.li,{children:["You can guess the whole word at once","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"If you get it right, you won, game ends."}),"\n",(0,s.jsx)(n.li,{children:"If you don't get it right, you get to see the secret, game ends."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"In case of end of input, game finishes via force."}),"\n",(0,s.jsx)(n.li,{children:"In case of invalid input, no guesses are subtracted, game carries on."}),"\n",(0,s.jsx)(n.li,{children:"Letters and words are not case sensitive."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"suggested-workflow",children:"Suggested workflow"}),"\n",(0,s.jsxs)(n.p,{children:["As we have talked about on the seminar, I suggest you to follow\n",(0,s.jsx)(n.em,{children:"Test-Driven Development"}),"\nin this case."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"TDD workflow",src:t(27420).Z+"",width:"2814",height:"1652"})}),"\n",(0,s.jsx)(n.p,{children:"In our current scenario we are already in the stage of refactoring and fixing the\nbugs. Therefore try to follow this succession of steps:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Try to reproduce the bug."}),"\n",(0,s.jsx)(n.li,{children:"Create a test that proves the presence of the bug."}),"\n",(0,s.jsx)(n.li,{children:"Fix the bug."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are submitting the bonus via GitLab, it is helpful to commit tests\nbefore commiting the fixes, so that it is apparent that the bug is manifested.\nExample of ",(0,s.jsx)(n.code,{children:"git log"})," (notice that the first line represents latest commit):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"feat: Implement fizz_buzzer\ntest: Add tests for fizz_buzzer\nfix: Fix NULL-check in print_name\ntest: Add test for NULL in print_name\n"})}),"\n",(0,s.jsx)(n.h2,{id:"tasks",children:"Tasks"}),"\n",(0,s.jsx)(n.p,{children:"As to your tasks, there are multiple things wrong in this project."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'There are 2 "bugs" that cannot be detected via tests, i.e. they are not bugs\nthat affect functionality of the game.'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["There is one evil bug in ",(0,s.jsx)(n.code,{children:"get_word"}),". It is not required to be fixed ;) Assign\nit the lowest priority."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"There are some tests failing. Please try to figure it out, so you have green\ntests for the rest :)"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["We have gotten a bug report for ",(0,s.jsx)(n.code,{children:"word_guessed"}),", all we got is"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["doesn't work when there are too many ",(0,s.jsx)(n.code,{children:"a"}),"s"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Please try to replicate the bug and create a tests, so we don't get any\nregression later on."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"One hidden bug :) Closely non-specified, we cannot reproduce it and we were\ndrunk while playing the game, so we don't remember a thing. :/"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Try to cover as much code via the tests as possible. We are not going to look\nat the metrics, but DRY is violated a lot, so as a last task try to remove as\nmuch of the duplicit code as possible."}),"\n",(0,s.jsx)(n.p,{children:"Tests should help you a lot in case there are some regressions."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["In case you wonder why there are always 3 same words in the file with words, it\nis because of the ",(0,s.jsx)(n.code,{children:"get_word"})," bug. It is not a bug that can be easily fixed, so\nit is a not requirement at all and you can still get all points for the bonus ;)"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Functional_testing",children:"Functional tests"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Smoke_testing_%28software%29",children:"Smoke test"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself",children:"DRY"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},27420:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/tdd_lifecycle-327ad9ee0ed8318ed11e19a28e02b2cc.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var s=t(67294);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/595c7293.8b475e77.js b/assets/js/595c7293.8b475e77.js new file mode 100644 index 0000000..51805ea --- /dev/null +++ b/assets/js/595c7293.8b475e77.js @@ -0,0 +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:1707050925,formattedLastUpdatedAt:"Feb 4, 2024",frontMatter:{id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},sidebar:"autogeneratedBar",previous:{title:"5th and 6th seminar",permalink:"/c/bonuses/seminar-05-06"},next:{title:"10th seminar",permalink:"/c/bonuses/seminar-10"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Warning",id:"warning",level:2},{value:"Testing",id:"testing",level:2},{value:"Task no. 1: Counting (0.75 K\u20a1)",id:"task-no-1-counting-075-k",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Bonus part (0.75 K\u20a1)",id:"bonus-part-075-k",level:3},{value:"Task no. 2: Weird trees (1 K\u20a1)",id:"task-no-2-weird-trees-1-k",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"8th-seminar-bonus-assignment",children:"8th seminar bonus assignment"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"pathname:///files/c/bonuses/08.tar.gz",children:"Source"})}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"In this bonus you can implement two tasks, one of them has a bonus part with generic\nsolution."}),"\n",(0,i.jsx)(n.p,{children:"One is focused on counting ananas or in case of generic version any substring in\nthe file, but with a restriction on the function you use."}),"\n",(0,i.jsx)(n.p,{children:"Other one has a more algorithmic spirit."}),"\n",(0,i.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,i.jsx)(n.h2,{id:"warning",children:"Warning"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"DO NOT COMMIT test data"})," to your own git repository, since the tests include\nfiles that exceed 10MB by themselves. Even if they are on separate branch, they\ntake up the space."]}),"\n",(0,i.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,i.jsxs)(n.p,{children:["For testing you are provided with python script (requires ",(0,i.jsx)(n.code,{children:"click"})," to be installed:\n",(0,i.jsx)(n.code,{children:"pip3 install --user click"}),") and ",(0,i.jsx)(n.code,{children:"Makefile"})," that provides following targets:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting-bonus"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests with bonus implemented"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check"})," - runs both ",(0,i.jsx)(n.code,{children:"counting"})," and ",(0,i.jsx)(n.code,{children:"counting-bonus"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"clean"})," - removes output files from the test runs"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-1-counting-075-k",children:"Task no. 1: Counting (0.75 K\u20a1)"}),"\n",(0,i.jsx)(n.p,{children:"Your first task is to make smallish program that counts occurences of specific\n(or given) word from file and writes the number to other file."}),"\n",(0,i.jsx)(n.p,{children:"Usage of the program is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Usage: ./counting [string-to-be-counted]\n"})}),"\n",(0,i.jsx)(n.p,{children:"Arguments that are passed to the program represent:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we count the words"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we output the count"]}),"\n",(0,i.jsxs)(n.li,{children:["(optional argument) ",(0,i.jsx)(n.code,{children:"[string-to-be-counted]"})," - in case you implement bonus,\notherwise we default to word ",(0,i.jsx)(n.code,{children:"ananas"})," ;)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In skeleton you are given 3 empty, but documented, functions to implement."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_anything"})," - function accepts input file and substring to be counted in\nthe file, returns the count."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_ananas"})," - same as ",(0,i.jsx)(n.code,{children:"count_anything"}),", but specialized for ananases, the\ndefault implementation from the skeleton expects you to implement ",(0,i.jsx)(n.code,{children:"count_anything"}),"\nand therefore it just calls the other function."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"write_number"})," - function that writes the number to the file, why would you\nneed the function is explained later :)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.p,{children:["For manipulation with the files you are only allowed to use ",(0,i.jsx)(n.code,{children:"fopen"}),", ",(0,i.jsx)(n.code,{children:"fclose"}),",\n",(0,i.jsx)(n.code,{children:"fgetc"})," and ",(0,i.jsx)(n.code,{children:"fputc"}),". Functions like ",(0,i.jsx)(n.code,{children:"fprintf"})," (except for ",(0,i.jsx)(n.code,{children:"stderr"})," or logging) and\n",(0,i.jsx)(n.code,{children:"fscanf"})," are ",(0,i.jsx)(n.strong,{children:"forbidden"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"In case you struggle and want to use one of those functions, the solution will be\npenalized by 50% of points."}),"\n",(0,i.jsx)(n.h3,{id:"bonus-part-075-k",children:"Bonus part (0.75 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["Bonus part of this assignment is to implement ",(0,i.jsx)(n.code,{children:"count_anything"})," rather than ",(0,i.jsx)(n.code,{children:"count_ananas"}),"."]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Smaller hint: This task does not need dynamic allocation :) You just need one\ngood helper function and the right idea ;)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-2-weird-trees-1-k",children:"Task no. 2: Weird trees (1 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["In this task we are crossing our paths with ",(0,i.jsx)(n.em,{children:"algorithms and data structures"}),".\nYour task is to write a program that constructs tree from the file that is given\nas an argument and pretty-prints it."]}),"\n",(0,i.jsxs)(n.p,{children:["Input file consists of lines, that include ",(0,i.jsx)(n.code,{children:"key"})," and ",(0,i.jsx)(n.code,{children:"rank"})," in form ",(0,i.jsx)(n.code,{children:"key;rank"}),"\nor ",(0,i.jsx)(n.code,{children:"nil"}),". Why would we have ",(0,i.jsx)(n.code,{children:"nil"})," in a file? The file represents pre-order iteration\nthrough the tree. Leaves never have rank different than 0, so you can safely assume\n2 non-existing ",(0,i.jsx)(n.code,{children:"nil"}),"s in the input after you read such node ;)"]}),"\n",(0,i.jsxs)("table",{children:[(0,i.jsxs)("tr",{children:[(0,i.jsx)("th",{children:"Example input file"}),(0,i.jsx)("th",{children:"Tree it represents"})]}),(0,i.jsxs)("tr",{children:[(0,i.jsx)("td",{children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8;4\n5;3\n3;2\n2;1\n1;0\nnil\n4;0\n7;1\n6;0\nnil\n11;2\n10;1\n9;0\nnil\n12;0\n"})})}),(0,i.jsx)("td",{children:(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"tree",src:t(30073).Z+"",width:"633",height:"684"})})})]})]}),"\n",(0,i.jsxs)(n.p,{children:["In this task you are only provided with different trees in the ",(0,i.jsx)(n.code,{children:"test-trees"})," directory.\nImplementation and format of the pretty-print is totally up to you. :)"]}),"\n",(0,i.jsx)(n.p,{children:"Example of mine for the tree above:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8 (rank = 4)\n+-- 5 (rank = 3)\n| +-- 3 (rank = 2)\n| | +-- 2 (rank = 1)\n| | | +-- 1 (rank = 0)\n| | +-- 4 (rank = 0)\n| +-- 7 (rank = 1)\n| +-- 6 (rank = 0)\n+-- 11 (rank = 2)\n +-- 10 (rank = 1)\n | +-- 9 (rank = 0)\n +-- 12 (rank = 0)\n"})}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Can you find out what are those trees? :)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,i.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,i.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},30073:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/tree-c9e37f87f9095c00fad33ea034485ce6.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>o});var i=t(67294);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/595c7293.e8aa1f47.js b/assets/js/595c7293.e8aa1f47.js deleted file mode 100644 index fc8d729..0000000 --- a/assets/js/595c7293.e8aa1f47.js +++ /dev/null @@ -1 +0,0 @@ -"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:1706528814,formattedLastUpdatedAt:"Jan 29, 2024",frontMatter:{id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},sidebar:"autogeneratedBar",previous:{title:"5th and 6th seminar",permalink:"/c/bonuses/seminar-05-06"},next:{title:"10th seminar",permalink:"/c/bonuses/seminar-10"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Warning",id:"warning",level:2},{value:"Testing",id:"testing",level:2},{value:"Task no. 1: Counting (0.75 K\u20a1)",id:"task-no-1-counting-075-k",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Bonus part (0.75 K\u20a1)",id:"bonus-part-075-k",level:3},{value:"Task no. 2: Weird trees (1 K\u20a1)",id:"task-no-2-weird-trees-1-k",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"8th-seminar-bonus-assignment",children:"8th seminar bonus assignment"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"pathname:///files/c/bonuses/08.tar.gz",children:"Source"})}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"In this bonus you can implement two tasks, one of them has a bonus part with generic\nsolution."}),"\n",(0,i.jsx)(n.p,{children:"One is focused on counting ananas or in case of generic version any substring in\nthe file, but with a restriction on the function you use."}),"\n",(0,i.jsx)(n.p,{children:"Other one has a more algorithmic spirit."}),"\n",(0,i.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,i.jsx)(n.h2,{id:"warning",children:"Warning"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"DO NOT COMMIT test data"})," to your own git repository, since the tests include\nfiles that exceed 10MB by themselves. Even if they are on separate branch, they\ntake up the space."]}),"\n",(0,i.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,i.jsxs)(n.p,{children:["For testing you are provided with python script (requires ",(0,i.jsx)(n.code,{children:"click"})," to be installed:\n",(0,i.jsx)(n.code,{children:"pip3 install --user click"}),") and ",(0,i.jsx)(n.code,{children:"Makefile"})," that provides following targets:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting-bonus"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests with bonus implemented"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check"})," - runs both ",(0,i.jsx)(n.code,{children:"counting"})," and ",(0,i.jsx)(n.code,{children:"counting-bonus"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"clean"})," - removes output files from the test runs"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-1-counting-075-k",children:"Task no. 1: Counting (0.75 K\u20a1)"}),"\n",(0,i.jsx)(n.p,{children:"Your first task is to make smallish program that counts occurences of specific\n(or given) word from file and writes the number to other file."}),"\n",(0,i.jsx)(n.p,{children:"Usage of the program is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Usage: ./counting [string-to-be-counted]\n"})}),"\n",(0,i.jsx)(n.p,{children:"Arguments that are passed to the program represent:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we count the words"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we output the count"]}),"\n",(0,i.jsxs)(n.li,{children:["(optional argument) ",(0,i.jsx)(n.code,{children:"[string-to-be-counted]"})," - in case you implement bonus,\notherwise we default to word ",(0,i.jsx)(n.code,{children:"ananas"})," ;)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In skeleton you are given 3 empty, but documented, functions to implement."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_anything"})," - function accepts input file and substring to be counted in\nthe file, returns the count."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_ananas"})," - same as ",(0,i.jsx)(n.code,{children:"count_anything"}),", but specialized for ananases, the\ndefault implementation from the skeleton expects you to implement ",(0,i.jsx)(n.code,{children:"count_anything"}),"\nand therefore it just calls the other function."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"write_number"})," - function that writes the number to the file, why would you\nneed the function is explained later :)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.p,{children:["For manipulation with the files you are only allowed to use ",(0,i.jsx)(n.code,{children:"fopen"}),", ",(0,i.jsx)(n.code,{children:"fclose"}),",\n",(0,i.jsx)(n.code,{children:"fgetc"})," and ",(0,i.jsx)(n.code,{children:"fputc"}),". Functions like ",(0,i.jsx)(n.code,{children:"fprintf"})," (except for ",(0,i.jsx)(n.code,{children:"stderr"})," or logging) and\n",(0,i.jsx)(n.code,{children:"fscanf"})," are ",(0,i.jsx)(n.strong,{children:"forbidden"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"In case you struggle and want to use one of those functions, the solution will be\npenalized by 50% of points."}),"\n",(0,i.jsx)(n.h3,{id:"bonus-part-075-k",children:"Bonus part (0.75 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["Bonus part of this assignment is to implement ",(0,i.jsx)(n.code,{children:"count_anything"})," rather than ",(0,i.jsx)(n.code,{children:"count_ananas"}),"."]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Smaller hint: This task does not need dynamic allocation :) You just need one\ngood helper function and the right idea ;)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-2-weird-trees-1-k",children:"Task no. 2: Weird trees (1 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["In this task we are crossing our paths with ",(0,i.jsx)(n.em,{children:"algorithms and data structures"}),".\nYour task is to write a program that constructs tree from the file that is given\nas an argument and pretty-prints it."]}),"\n",(0,i.jsxs)(n.p,{children:["Input file consists of lines, that include ",(0,i.jsx)(n.code,{children:"key"})," and ",(0,i.jsx)(n.code,{children:"rank"})," in form ",(0,i.jsx)(n.code,{children:"key;rank"}),"\nor ",(0,i.jsx)(n.code,{children:"nil"}),". Why would we have ",(0,i.jsx)(n.code,{children:"nil"})," in a file? The file represents pre-order iteration\nthrough the tree. Leaves never have rank different than 0, so you can safely assume\n2 non-existing ",(0,i.jsx)(n.code,{children:"nil"}),"s in the input after you read such node ;)"]}),"\n",(0,i.jsxs)("table",{children:[(0,i.jsxs)("tr",{children:[(0,i.jsx)("th",{children:"Example input file"}),(0,i.jsx)("th",{children:"Tree it represents"})]}),(0,i.jsxs)("tr",{children:[(0,i.jsx)("td",{children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8;4\n5;3\n3;2\n2;1\n1;0\nnil\n4;0\n7;1\n6;0\nnil\n11;2\n10;1\n9;0\nnil\n12;0\n"})})}),(0,i.jsx)("td",{children:(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"tree",src:t(30073).Z+"",width:"633",height:"684"})})})]})]}),"\n",(0,i.jsxs)(n.p,{children:["In this task you are only provided with different trees in the ",(0,i.jsx)(n.code,{children:"test-trees"})," directory.\nImplementation and format of the pretty-print is totally up to you. :)"]}),"\n",(0,i.jsx)(n.p,{children:"Example of mine for the tree above:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8 (rank = 4)\n+-- 5 (rank = 3)\n| +-- 3 (rank = 2)\n| | +-- 2 (rank = 1)\n| | | +-- 1 (rank = 0)\n| | +-- 4 (rank = 0)\n| +-- 7 (rank = 1)\n| +-- 6 (rank = 0)\n+-- 11 (rank = 2)\n +-- 10 (rank = 1)\n | +-- 9 (rank = 0)\n +-- 12 (rank = 0)\n"})}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Can you find out what are those trees? :)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,i.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,i.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},30073:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/tree-c9e37f87f9095c00fad33ea034485ce6.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>o});var i=t(67294);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7052c0bc.61d77968.js b/assets/js/7052c0bc.61d77968.js deleted file mode 100644 index 272dd7b..0000000 --- a/assets/js/7052c0bc.61d77968.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[9731],{42286:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var o=n(85893),r=n(11151);const i={id:"cpp-intro",title:"Introduction",slug:"/"},c=void 0,a={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:1706528814,formattedLastUpdatedAt:"Jan 29, 2024",sidebarPosition:0,frontMatter:{id:"cpp-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Exceptions and RAII",permalink:"/cpp/category/exceptions-and-raii"}},s={},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:()=>a,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 a(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/7052c0bc.cf9e5f57.js b/assets/js/7052c0bc.cf9e5f57.js new file mode 100644 index 0000000..fccebf4 --- /dev/null +++ b/assets/js/7052c0bc.cf9e5f57.js @@ -0,0 +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:1707050925,formattedLastUpdatedAt:"Feb 4, 2024",sidebarPosition:0,frontMatter:{id:"cpp-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Exceptions and RAII",permalink:"/cpp/category/exceptions-and-raii"}},a={},p=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},11151:(t,e,n)=>{n.d(e,{Z:()=>s,a:()=>c});var o=n(67294);const r={},i=o.createContext(r);function c(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:c(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/794ef108.083736fa.js b/assets/js/794ef108.083736fa.js new file mode 100644 index 0000000..15a8672 --- /dev/null +++ b/assets/js/794ef108.083736fa.js @@ -0,0 +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:1707050925,formattedLastUpdatedAt:"Feb 4, 2024",sidebarPosition:0,frontMatter:{id:"c-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Bonuses",permalink:"/c/category/bonuses"}},a={},u=[];function d(t){return(0,o.jsx)(o.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(d,{...t})}):d()}},11151:(t,e,n)=>{n.d(e,{Z:()=>c,a:()=>s});var o=n(67294);const r={},i=o.createContext(r);function s(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/794ef108.8d36eaa9.js b/assets/js/794ef108.8d36eaa9.js deleted file mode 100644 index e8edbdd..0000000 --- a/assets/js/794ef108.8d36eaa9.js +++ /dev/null @@ -1 +0,0 @@ -"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:1706528814,formattedLastUpdatedAt:"Jan 29, 2024",sidebarPosition:0,frontMatter:{id:"c-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Bonuses",permalink:"/c/category/bonuses"}},a={},u=[];function d(t){return(0,o.jsx)(o.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(d,{...t})}):d()}},11151:(t,e,n)=>{n.d(e,{Z:()=>c,a:()=>s});var o=n(67294);const r={},i=o.createContext(r);function s(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/84d1e0d8.478c5852.js b/assets/js/84d1e0d8.478c5852.js new file mode 100644 index 0000000..a96a510 --- /dev/null +++ b/assets/js/84d1e0d8.478c5852.js @@ -0,0 +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:1707050925,formattedLastUpdatedAt:"Feb 4, 2024",sidebarPosition:0,frontMatter:{id:"algorithms-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Algorithms and Correctness",permalink:"/algorithms/category/algorithms-and-correctness"}},c={},d=[];function l(t){const e={a:"a",em:"em",p:"p",...(0,s.a)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(e.p,{children:["In this part you can find \u201crandom\u201d additional materials I have written over the\ncourse of teaching ",(0,o.jsx)(e.em,{children:"Algorithms and data structures I"}),"."]}),"\n",(0,o.jsx)(e.p,{children:"It is a various mix of stuff that may have been produced as a follow-up on some\nquestion asked at the seminar or spontanously."}),"\n",(0,o.jsxs)(e.p,{children:["If you have some ideas for posts, please do not hesitate to submit them as issues\nin the linked ",(0,o.jsx)(e.a,{href:"https://gitlab.fi.muni.cz/xfocko/kb/issues",children:"GitLab"}),"."]})]})}function u(t={}){const{wrapper:e}={...(0,s.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(l,{...t})}):l(t)}},11151:(t,e,n)=>{n.d(e,{Z:()=>a,a:()=>i});var o=n(67294);const s={},r=o.createContext(s);function i(t){const e=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),o.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/84d1e0d8.f337d099.js b/assets/js/84d1e0d8.f337d099.js deleted file mode 100644 index 6a2d854..0000000 --- a/assets/js/84d1e0d8.f337d099.js +++ /dev/null @@ -1 +0,0 @@ -"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:1706528814,formattedLastUpdatedAt:"Jan 29, 2024",sidebarPosition:0,frontMatter:{id:"algorithms-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Algorithms and Correctness",permalink:"/algorithms/category/algorithms-and-correctness"}},c={},d=[];function l(t){const e={a:"a",em:"em",p:"p",...(0,s.a)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(e.p,{children:["In this part you can find \u201crandom\u201d additional materials I have written over the\ncourse of teaching ",(0,o.jsx)(e.em,{children:"Algorithms and data structures I"}),"."]}),"\n",(0,o.jsx)(e.p,{children:"It is a various mix of stuff that may have been produced as a follow-up on some\nquestion asked at the seminar or spontanously."}),"\n",(0,o.jsxs)(e.p,{children:["If you have some ideas for posts, please do not hesitate to submit them as issues\nin the linked ",(0,o.jsx)(e.a,{href:"https://gitlab.fi.muni.cz/xfocko/kb/issues",children:"GitLab"}),"."]})]})}function u(t={}){const{wrapper:e}={...(0,s.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(l,{...t})}):l(t)}},11151:(t,e,n)=>{n.d(e,{Z:()=>a,a:()=>i});var o=n(67294);const s={},r=o.createContext(s);function i(t){const e=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),o.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1288602.19054c2d.js b/assets/js/b1288602.19054c2d.js deleted file mode 100644 index 150fa61..0000000 --- a/assets/js/b1288602.19054c2d.js +++ /dev/null @@ -1 +0,0 @@ -"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:1706528814,formattedLastUpdatedAt:"Jan 29, 2024",frontMatter:{title:"Submitting merge requests"},sidebar:"autogeneratedBar",previous:{title:"Practice exam C",permalink:"/c/pexam/cams"}},c={},h=[{value:"Tutorial",id:"tutorial",level:2},{value:"Step #1 - Starting from the clean repository",id:"step-1---starting-from-the-clean-repository",level:3},{value:"Step #2 - Create new branch",id:"step-2---create-new-branch",level:3},{value:"Step #3 - Do the assignment",id:"step-3---do-the-assignment",level:3},{value:"Step #4 - Commit and upload the changes to GitLab",id:"step-4---commit-and-upload-the-changes-to-gitlab",level:3},{value:"Step #5 - Creating a merge request manually",id:"step-5---creating-a-merge-request-manually",level:3},{value:"Step #6 - Set assignees",id:"step-6---set-assignees",level:3},{value:"Step #7 - Return to default branch",id:"step-7---return-to-default-branch",level:3}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"submitting-merge-requests-for-review",children:"Submitting merge requests for review"}),"\n",(0,r.jsxs)(n.p,{children:["This tutorial aims to show you how to follow basic git workflow and submit changes\nthrough ",(0,r.jsx)(n.em,{children:"Merge Requests"})," for review."]}),"\n",(0,r.jsxs)(n.p,{children:["The rudimentary idea behind aims for changes to be present on a separate branch\nthat is supposedly ",(0,r.jsx)(n.em,{children:"merged"})," into the default branch. Till then changes can be reviewed\non ",(0,r.jsx)(n.em,{children:"Merge Request"})," and additional changes may be made based on the reviews. Once\nthe changes satisfy requirements, the merge request is merged."]}),"\n",(0,r.jsx)(n.h2,{id:"tutorial",children:"Tutorial"}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["Use this tutorial only for bonus assignments ",(0,r.jsx)(n.strong,{children:"made by your tutors"})," or in case\nyou need to make up for the absence."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-1---starting-from-the-clean-repository",children:"Step #1 - Starting from the clean repository"}),"\n",(0,r.jsxs)(n.p,{children:["In your repository (either locally or on aisa) type ",(0,r.jsx)(n.code,{children:"git status"})," and check if your\nrepository is clean and you are present on the main branch (",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"})," or\n",(0,r.jsx)(n.code,{children:"trunk"}),"). If you do not know what your default branch is, it is probably ",(0,r.jsx)(n.code,{children:"master"}),"\nand you should not be on any other branch."]}),"\n",(0,r.jsx)(n.p,{children:"Output of the command should look like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\nOn branch master # Or main or trunk.\nYour branch is up to date with 'origin/master'.\n\nnothing to commit, working tree clean\n"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["In case you are on different branch or there are uncommitted changes,\n",(0,r.jsx)(n.strong,{children:"do not continue!!!"})," Clean your repository (commit the changes or discard\nthem), before you continue."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-2---create-new-branch",children:"Step #2 - Create new branch"}),"\n",(0,r.jsx)(n.p,{children:"In your repository write command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git checkout -b BRANCH\nSwitched to a new branch 'BRANCH'\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Instead of ",(0,r.jsx)(n.code,{children:"BRANCH"})," use some reasonable name for the branch. For example if you\nare working on the seminar from 3rd week, name the branch ",(0,r.jsx)(n.code,{children:"seminar-03"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-3---do-the-assignment",children:"Step #3 - Do the assignment"}),"\n",(0,r.jsx)(n.p,{children:"Download the skeleton for the seminar assignment, extract and program. For example\nif you are working on 3rd seminar, you can do so by:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ wget https://www.fi.muni.cz/pb071/seminars/seminar-03/pb071-seminar-03.zip\naisa$ unzip pb071-seminar-03.zip\n# Now you should have directory 'seminar-03'.\naisa$ rm pb071-seminar-03.zip\naisa$ cd seminar-03\n# You can work on the assignment.\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-4---commit-and-upload-the-changes-to-gitlab",children:"Step #4 - Commit and upload the changes to GitLab"}),"\n",(0,r.jsxs)(n.p,{children:["The same way you ",(0,r.jsx)(n.em,{children:"add"})," and ",(0,r.jsx)(n.em,{children:"commit"})," files for the homework assignments, you do for\nthe seminar."]}),"\n",(0,r.jsxs)(n.p,{children:["Now you can upload the changes to GitLab. ",(0,r.jsx)(n.code,{children:"git push"})," is not enough, since repository\non GitLab does not know your new branch. You can solve this by adding arguments:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git push origin BRANCH\n...\nremote: To create a merge request for BRANCH, visit:\nremote: https://gitlab.fi.muni.cz/login/pb071/merge_requests/new?merge_request%5Bsource_branch%5D=BRANCH\n...\n"})}),"\n",(0,r.jsx)(n.p,{children:"In the output you should have a link for creating a merge request. If you see this\nlink, open it and skip next step."}),"\n",(0,r.jsx)(n.h3,{id:"step-5---creating-a-merge-request-manually",children:"Step #5 - Creating a merge request manually"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Open your repository on GitLab."}),"\n",(0,r.jsxs)(n.li,{children:["On the left panel click on ",(0,r.jsx)(n.em,{children:"Merge Requests"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"New Merge Request"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Source branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and ",(0,r.jsx)(n.code,{children:"BRANCH"}),", which you created."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Target branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and your default branch you have seen\nin the output of the first command. (most likely ",(0,r.jsx)(n.code,{children:"master"}),")"]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"Compare branches and continue"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-6---set-assignees",children:"Step #6 - Set assignees"}),"\n",(0,r.jsxs)(n.p,{children:["On the page that is opened, please check at the top that you are creating merge\nrequest ",(0,r.jsx)(n.strong,{children:"from"})," your new branch ",(0,r.jsx)(n.strong,{children:"to"})," your default branch (one of ",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"}),"\nor ",(0,r.jsx)(n.code,{children:"trunk"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["Then in the field ",(0,r.jsx)(n.em,{children:"Assignees"})," set your tutors based on the seminar group. You can\nuse login for a quick look up."]}),"\n",(0,r.jsxs)(n.p,{children:["In the end click on ",(0,r.jsx)(n.em,{children:"Submit merge request"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-7---return-to-default-branch",children:"Step #7 - Return to default branch"}),"\n",(0,r.jsx)(n.p,{children:"Homework assignments can be submitted only from branches specified in the rules\nfor the course. Because of that, before you do anything else, you should switch\nback to your default branch."}),"\n",(0,r.jsxs)(n.p,{children:["First of all, same as in step #1, check that your repository is clean with ",(0,r.jsx)(n.code,{children:"git status"}),".\nFor the sake of safety, do not continue without clean repository. Then with command\n",(0,r.jsx)(n.code,{children:"git checkout BRANCH"})," switch to your default branch ",(0,r.jsx)(n.code,{children:"BRANCH"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["If you do not know which branch is your default, try ",(0,r.jsx)(n.code,{children:"git branch"})," that outputs all branches in your repository. Default branch is typically ",(0,r.jsx)(n.code,{children:"master"}),", but can\nbe ",(0,r.jsx)(n.code,{children:"main"})," or ",(0,r.jsx)(n.code,{children:"trunk"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\n# Check if repository is clean\n\n# If you know, what is your default branch, you can skip next command.\naisa$ git branch\n# Find the default branch in the list; should be one of the `master`, `main` or\n# `trunk` and you should not have more than one of those.\n# In case the list clears the terminal and you cannot see shell prompt, you can\n# press `q` to quit the pager.\n\naisa$ git checkout master\n"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["Adapted from: ",(0,r.jsx)(n.a,{href:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html",children:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html"})]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>i});var r=t(67294);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1288602.9aa1a8e6.js b/assets/js/b1288602.9aa1a8e6.js new file mode 100644 index 0000000..c967676 --- /dev/null +++ b/assets/js/b1288602.9aa1a8e6.js @@ -0,0 +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:1707050925,formattedLastUpdatedAt:"Feb 4, 2024",frontMatter:{title:"Submitting merge requests"},sidebar:"autogeneratedBar",previous:{title:"Practice exam C",permalink:"/c/pexam/cams"}},c={},h=[{value:"Tutorial",id:"tutorial",level:2},{value:"Step #1 - Starting from the clean repository",id:"step-1---starting-from-the-clean-repository",level:3},{value:"Step #2 - Create new branch",id:"step-2---create-new-branch",level:3},{value:"Step #3 - Do the assignment",id:"step-3---do-the-assignment",level:3},{value:"Step #4 - Commit and upload the changes to GitLab",id:"step-4---commit-and-upload-the-changes-to-gitlab",level:3},{value:"Step #5 - Creating a merge request manually",id:"step-5---creating-a-merge-request-manually",level:3},{value:"Step #6 - Set assignees",id:"step-6---set-assignees",level:3},{value:"Step #7 - Return to default branch",id:"step-7---return-to-default-branch",level:3}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"submitting-merge-requests-for-review",children:"Submitting merge requests for review"}),"\n",(0,r.jsxs)(n.p,{children:["This tutorial aims to show you how to follow basic git workflow and submit changes\nthrough ",(0,r.jsx)(n.em,{children:"Merge Requests"})," for review."]}),"\n",(0,r.jsxs)(n.p,{children:["The rudimentary idea behind aims for changes to be present on a separate branch\nthat is supposedly ",(0,r.jsx)(n.em,{children:"merged"})," into the default branch. Till then changes can be reviewed\non ",(0,r.jsx)(n.em,{children:"Merge Request"})," and additional changes may be made based on the reviews. Once\nthe changes satisfy requirements, the merge request is merged."]}),"\n",(0,r.jsx)(n.h2,{id:"tutorial",children:"Tutorial"}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["Use this tutorial only for bonus assignments ",(0,r.jsx)(n.strong,{children:"made by your tutors"})," or in case\nyou need to make up for the absence."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-1---starting-from-the-clean-repository",children:"Step #1 - Starting from the clean repository"}),"\n",(0,r.jsxs)(n.p,{children:["In your repository (either locally or on aisa) type ",(0,r.jsx)(n.code,{children:"git status"})," and check if your\nrepository is clean and you are present on the main branch (",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"})," or\n",(0,r.jsx)(n.code,{children:"trunk"}),"). If you do not know what your default branch is, it is probably ",(0,r.jsx)(n.code,{children:"master"}),"\nand you should not be on any other branch."]}),"\n",(0,r.jsx)(n.p,{children:"Output of the command should look like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\nOn branch master # Or main or trunk.\nYour branch is up to date with 'origin/master'.\n\nnothing to commit, working tree clean\n"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["In case you are on different branch or there are uncommitted changes,\n",(0,r.jsx)(n.strong,{children:"do not continue!!!"})," Clean your repository (commit the changes or discard\nthem), before you continue."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-2---create-new-branch",children:"Step #2 - Create new branch"}),"\n",(0,r.jsx)(n.p,{children:"In your repository write command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git checkout -b BRANCH\nSwitched to a new branch 'BRANCH'\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Instead of ",(0,r.jsx)(n.code,{children:"BRANCH"})," use some reasonable name for the branch. For example if you\nare working on the seminar from 3rd week, name the branch ",(0,r.jsx)(n.code,{children:"seminar-03"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-3---do-the-assignment",children:"Step #3 - Do the assignment"}),"\n",(0,r.jsx)(n.p,{children:"Download the skeleton for the seminar assignment, extract and program. For example\nif you are working on 3rd seminar, you can do so by:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ wget https://www.fi.muni.cz/pb071/seminars/seminar-03/pb071-seminar-03.zip\naisa$ unzip pb071-seminar-03.zip\n# Now you should have directory 'seminar-03'.\naisa$ rm pb071-seminar-03.zip\naisa$ cd seminar-03\n# You can work on the assignment.\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-4---commit-and-upload-the-changes-to-gitlab",children:"Step #4 - Commit and upload the changes to GitLab"}),"\n",(0,r.jsxs)(n.p,{children:["The same way you ",(0,r.jsx)(n.em,{children:"add"})," and ",(0,r.jsx)(n.em,{children:"commit"})," files for the homework assignments, you do for\nthe seminar."]}),"\n",(0,r.jsxs)(n.p,{children:["Now you can upload the changes to GitLab. ",(0,r.jsx)(n.code,{children:"git push"})," is not enough, since repository\non GitLab does not know your new branch. You can solve this by adding arguments:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git push origin BRANCH\n...\nremote: To create a merge request for BRANCH, visit:\nremote: https://gitlab.fi.muni.cz/login/pb071/merge_requests/new?merge_request%5Bsource_branch%5D=BRANCH\n...\n"})}),"\n",(0,r.jsx)(n.p,{children:"In the output you should have a link for creating a merge request. If you see this\nlink, open it and skip next step."}),"\n",(0,r.jsx)(n.h3,{id:"step-5---creating-a-merge-request-manually",children:"Step #5 - Creating a merge request manually"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Open your repository on GitLab."}),"\n",(0,r.jsxs)(n.li,{children:["On the left panel click on ",(0,r.jsx)(n.em,{children:"Merge Requests"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"New Merge Request"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Source branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and ",(0,r.jsx)(n.code,{children:"BRANCH"}),", which you created."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Target branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and your default branch you have seen\nin the output of the first command. (most likely ",(0,r.jsx)(n.code,{children:"master"}),")"]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"Compare branches and continue"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-6---set-assignees",children:"Step #6 - Set assignees"}),"\n",(0,r.jsxs)(n.p,{children:["On the page that is opened, please check at the top that you are creating merge\nrequest ",(0,r.jsx)(n.strong,{children:"from"})," your new branch ",(0,r.jsx)(n.strong,{children:"to"})," your default branch (one of ",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"}),"\nor ",(0,r.jsx)(n.code,{children:"trunk"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["Then in the field ",(0,r.jsx)(n.em,{children:"Assignees"})," set your tutors based on the seminar group. You can\nuse login for a quick look up."]}),"\n",(0,r.jsxs)(n.p,{children:["In the end click on ",(0,r.jsx)(n.em,{children:"Submit merge request"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-7---return-to-default-branch",children:"Step #7 - Return to default branch"}),"\n",(0,r.jsx)(n.p,{children:"Homework assignments can be submitted only from branches specified in the rules\nfor the course. Because of that, before you do anything else, you should switch\nback to your default branch."}),"\n",(0,r.jsxs)(n.p,{children:["First of all, same as in step #1, check that your repository is clean with ",(0,r.jsx)(n.code,{children:"git status"}),".\nFor the sake of safety, do not continue without clean repository. Then with command\n",(0,r.jsx)(n.code,{children:"git checkout BRANCH"})," switch to your default branch ",(0,r.jsx)(n.code,{children:"BRANCH"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["If you do not know which branch is your default, try ",(0,r.jsx)(n.code,{children:"git branch"})," that outputs all branches in your repository. Default branch is typically ",(0,r.jsx)(n.code,{children:"master"}),", but can\nbe ",(0,r.jsx)(n.code,{children:"main"})," or ",(0,r.jsx)(n.code,{children:"trunk"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\n# Check if repository is clean\n\n# If you know, what is your default branch, you can skip next command.\naisa$ git branch\n# Find the default branch in the list; should be one of the `master`, `main` or\n# `trunk` and you should not have more than one of those.\n# In case the list clears the terminal and you cannot see shell prompt, you can\n# press `q` to quit the pager.\n\naisa$ git checkout master\n"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["Adapted from: ",(0,r.jsx)(n.a,{href:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html",children:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html"})]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>i});var r=t(67294);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d05e838c.0813f6b5.js b/assets/js/d05e838c.0813f6b5.js new file mode 100644 index 0000000..3427969 --- /dev/null +++ b/assets/js/d05e838c.0813f6b5.js @@ -0,0 +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:1707050925,formattedLastUpdatedAt:"Feb 4, 2024",frontMatter:{id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},sidebar:"autogeneratedBar",previous:{title:"4th seminar",permalink:"/c/bonuses/seminar-04"},next:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Task no. 1: Reverse (0.5 K\u20a1)",id:"task-no-1-reverse-05-k",level:3},{value:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)",id:"task-no-2-vigen\xe8re-05-k",level:3},{value:"Bonus part (0.5 K\u20a1)",id:"bonus-part-05-k",level:4},{value:"Task no. 3: Bit madness (0.5 K\u20a1)",id:"task-no-3-bit-madness-05-k",level:3},{value:"Task no. 4: All combined to BMP (0.5 K\u20a1)",id:"task-no-4-all-combined-to-bmp-05-k",level:3},{value:"Submitting",id:"submitting",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/05-06.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"In this bonus you will implement few functions that will be used together for\nimplementing a very special cipher."}),"\n",(0,s.jsx)(n.h3,{id:"task-no-1-reverse-05-k",children:"Task no. 1: Reverse (0.5 K\u20a1)"}),"\n",(0,s.jsxs)(n.p,{children:["Write a function ",(0,s.jsx)(n.code,{children:"char* reverse(const char* text)"})," that returns copy of the input\nstring in reversed order (also uppercase)."]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are given ",(0,s.jsx)(n.code,{children:"NULL"}),", return ",(0,s.jsx)(n.code,{children:"NULL"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Example (more in tests):"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char* reversed = reverse("Hello world!");\n\nprintf("%s\\n", reversed);\n// "!DLROW OLLEH"\n\nif (reversed != NULL) {\n free(reversed);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-2-vigen\xe8re-05-k",children:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Vigen\xe8re cipher is similar to the Caesar cipher, but you also have a key that is\nused for encrypting (or decrypting)."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to write two functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_encrypt(const char* key, const char* text)"})," for encrypting"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_decrypt(const char* key, const char* text)"})," for decrypting"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In both of those you should return uppercase characters."}),"\n",(0,s.jsx)(n.p,{children:"Meaning of the parameters you are given:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"key"})," - String that represents key that is used for *crypting. It consists of\none word and can have only characters of the alphabet. Does not matter if they\nare uppercase or lowercase."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"text"})," - String that is to be *crypted."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Function returns address of the encrypted (or decrypted) string. Or ",(0,s.jsx)(n.code,{children:"NULL"})," in case\nerror occurs."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char *encrypted = vigenere_encrypt("CoMPuTeR", "Hello world!");\n\nprintf("%s\\n", encrypted);\n// "JSXAI PSINR!"\n\nif (encrypted != NULL) {\n free(encrypted)\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"bonus-part-05-k",children:"Bonus part (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"If you can utilize helper function that would do both encrypting and decrypting,\nyou can gain 0.5 K\u20a1."}),"\n",(0,s.jsxs)(n.p,{children:["Usage of ",(0,s.jsx)(n.code,{children:"true"}),"/",(0,s.jsx)(n.code,{children:"false"})," to decide path in code is prohibited. It leads to merging\nof both functions into one. Point of this part is to discover a way to do this\ngenerically in such way that there are no separate paths for one or the other. One\nfunction with no branching for both of them, parametrization is your friend :)"]}),"\n",(0,s.jsx)(n.h3,{id:"task-no-3-bit-madness-05-k",children:"Task no. 3: Bit madness (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"This is a state of the art crypto. Please do not share :)"}),"\n",(0,s.jsx)(n.p,{children:"For encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Split the character that is to be encrypted in halves (4 and 4 bits each)."}),"\n",(0,s.jsx)(n.li,{children:"Bits in 1st half are to be split into pairs. Swap bits in those pairs."}),"\n",(0,s.jsxs)(n.li,{children:["Then use the 4 bits that you created in the 2nd step for ",(0,s.jsx)(n.code,{children:"XOR"})," with the other\n4 bits."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This simple and ingenious principle will be illustrated on the following example.\nString we want to encrypt is ",(0,s.jsx)(n.code,{children:"Hello world!"}),". We need to encrypt each letter separately,\nso we will demonstrate on letter ",(0,s.jsx)(n.code,{children:"H"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Letter ",(0,s.jsx)(n.code,{children:"H"})," is represented in ASCII as ",(0,s.jsx)(n.code,{children:"72"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"72"})," represented in binary is: ",(0,s.jsx)(n.code,{children:"01001000"}),". So first 4 bits are: ",(0,s.jsx)(n.code,{children:"0100"})," and last\n4 bits are ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["First half of bits (",(0,s.jsx)(n.code,{children:"0100"}),") consists of 2 pairs (",(0,s.jsx)(n.code,{children:"01"})," and ",(0,s.jsx)(n.code,{children:"00"}),") which we swap\n(",(0,s.jsx)(n.code,{children:"01 ~> 10"})," and ",(0,s.jsx)(n.code,{children:"00 ~> 00"}),"). That way we get ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"That half is used for xor with the other 4 bits:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" 1000 // second half\nXOR 1000 // first half after 2nd step\n--------\n 0000\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Now we combine both halves (first one is ",(0,s.jsx)(n.code,{children:"1000"}),", which we got from the 2nd step\nand second one is ",(0,s.jsx)(n.code,{children:"0000"}),", which we got from the 3rd step) and get ",(0,s.jsx)(n.code,{children:"10000000"}),",\nwhich is encrypted character ",(0,s.jsx)(n.code,{children:"H"})," using this method."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In case of decryption, reverse those steps."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to implement functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bit_encrypt(const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bit_decrypt(const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'unsigned char* encrypted = bit_encrypt("Hello world!");\n\nfor (int i = 0; i < 12;i++) {\n printf("%x ", encrypted[i]);\n //80 9c 95 95 96 11 bc 96 b9 95 9d 10\n}\n\nif (encrypted != NULL) {\n free(encrypted);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-4-all-combined-to-bmp-05-k",children:"Task no. 4: All combined to BMP (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Authors of the BMP cipher are non-disclosed :)"}),"\n",(0,s.jsx)(n.p,{children:"Create pair of functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bmp_encrypt(const char* key, const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bmp_decrypt(const char* key, const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"BMP cipher consists of following steps for encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Reverse the input string"}),"\n",(0,s.jsx)(n.li,{children:"Use Vigenere on the string you got from step #1"}),"\n",(0,s.jsx)(n.li,{children:"Use bit madness on the string you got from step #2"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For decrypting, reverse the steps."}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function a(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>c});var s=r(67294);const t={},i=s.createContext(t);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d05e838c.642ce149.js b/assets/js/d05e838c.642ce149.js deleted file mode 100644 index 53a011b..0000000 --- a/assets/js/d05e838c.642ce149.js +++ /dev/null @@ -1 +0,0 @@ -"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:1706528814,formattedLastUpdatedAt:"Jan 29, 2024",frontMatter:{id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},sidebar:"autogeneratedBar",previous:{title:"4th seminar",permalink:"/c/bonuses/seminar-04"},next:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Task no. 1: Reverse (0.5 K\u20a1)",id:"task-no-1-reverse-05-k",level:3},{value:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)",id:"task-no-2-vigen\xe8re-05-k",level:3},{value:"Bonus part (0.5 K\u20a1)",id:"bonus-part-05-k",level:4},{value:"Task no. 3: Bit madness (0.5 K\u20a1)",id:"task-no-3-bit-madness-05-k",level:3},{value:"Task no. 4: All combined to BMP (0.5 K\u20a1)",id:"task-no-4-all-combined-to-bmp-05-k",level:3},{value:"Submitting",id:"submitting",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/05-06.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"In this bonus you will implement few functions that will be used together for\nimplementing a very special cipher."}),"\n",(0,s.jsx)(n.h3,{id:"task-no-1-reverse-05-k",children:"Task no. 1: Reverse (0.5 K\u20a1)"}),"\n",(0,s.jsxs)(n.p,{children:["Write a function ",(0,s.jsx)(n.code,{children:"char* reverse(const char* text)"})," that returns copy of the input\nstring in reversed order (also uppercase)."]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are given ",(0,s.jsx)(n.code,{children:"NULL"}),", return ",(0,s.jsx)(n.code,{children:"NULL"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Example (more in tests):"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char* reversed = reverse("Hello world!");\n\nprintf("%s\\n", reversed);\n// "!DLROW OLLEH"\n\nif (reversed != NULL) {\n free(reversed);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-2-vigen\xe8re-05-k",children:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Vigen\xe8re cipher is similar to the Caesar cipher, but you also have a key that is\nused for encrypting (or decrypting)."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to write two functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_encrypt(const char* key, const char* text)"})," for encrypting"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_decrypt(const char* key, const char* text)"})," for decrypting"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In both of those you should return uppercase characters."}),"\n",(0,s.jsx)(n.p,{children:"Meaning of the parameters you are given:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"key"})," - String that represents key that is used for *crypting. It consists of\none word and can have only characters of the alphabet. Does not matter if they\nare uppercase or lowercase."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"text"})," - String that is to be *crypted."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Function returns address of the encrypted (or decrypted) string. Or ",(0,s.jsx)(n.code,{children:"NULL"})," in case\nerror occurs."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char *encrypted = vigenere_encrypt("CoMPuTeR", "Hello world!");\n\nprintf("%s\\n", encrypted);\n// "JSXAI PSINR!"\n\nif (encrypted != NULL) {\n free(encrypted)\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"bonus-part-05-k",children:"Bonus part (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"If you can utilize helper function that would do both encrypting and decrypting,\nyou can gain 0.5 K\u20a1."}),"\n",(0,s.jsxs)(n.p,{children:["Usage of ",(0,s.jsx)(n.code,{children:"true"}),"/",(0,s.jsx)(n.code,{children:"false"})," to decide path in code is prohibited. It leads to merging\nof both functions into one. Point of this part is to discover a way to do this\ngenerically in such way that there are no separate paths for one or the other. One\nfunction with no branching for both of them, parametrization is your friend :)"]}),"\n",(0,s.jsx)(n.h3,{id:"task-no-3-bit-madness-05-k",children:"Task no. 3: Bit madness (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"This is a state of the art crypto. Please do not share :)"}),"\n",(0,s.jsx)(n.p,{children:"For encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Split the character that is to be encrypted in halves (4 and 4 bits each)."}),"\n",(0,s.jsx)(n.li,{children:"Bits in 1st half are to be split into pairs. Swap bits in those pairs."}),"\n",(0,s.jsxs)(n.li,{children:["Then use the 4 bits that you created in the 2nd step for ",(0,s.jsx)(n.code,{children:"XOR"})," with the other\n4 bits."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This simple and ingenious principle will be illustrated on the following example.\nString we want to encrypt is ",(0,s.jsx)(n.code,{children:"Hello world!"}),". We need to encrypt each letter separately,\nso we will demonstrate on letter ",(0,s.jsx)(n.code,{children:"H"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Letter ",(0,s.jsx)(n.code,{children:"H"})," is represented in ASCII as ",(0,s.jsx)(n.code,{children:"72"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"72"})," represented in binary is: ",(0,s.jsx)(n.code,{children:"01001000"}),". So first 4 bits are: ",(0,s.jsx)(n.code,{children:"0100"})," and last\n4 bits are ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["First half of bits (",(0,s.jsx)(n.code,{children:"0100"}),") consists of 2 pairs (",(0,s.jsx)(n.code,{children:"01"})," and ",(0,s.jsx)(n.code,{children:"00"}),") which we swap\n(",(0,s.jsx)(n.code,{children:"01 ~> 10"})," and ",(0,s.jsx)(n.code,{children:"00 ~> 00"}),"). That way we get ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"That half is used for xor with the other 4 bits:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" 1000 // second half\nXOR 1000 // first half after 2nd step\n--------\n 0000\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Now we combine both halves (first one is ",(0,s.jsx)(n.code,{children:"1000"}),", which we got from the 2nd step\nand second one is ",(0,s.jsx)(n.code,{children:"0000"}),", which we got from the 3rd step) and get ",(0,s.jsx)(n.code,{children:"10000000"}),",\nwhich is encrypted character ",(0,s.jsx)(n.code,{children:"H"})," using this method."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In case of decryption, reverse those steps."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to implement functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bit_encrypt(const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bit_decrypt(const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'unsigned char* encrypted = bit_encrypt("Hello world!");\n\nfor (int i = 0; i < 12;i++) {\n printf("%x ", encrypted[i]);\n //80 9c 95 95 96 11 bc 96 b9 95 9d 10\n}\n\nif (encrypted != NULL) {\n free(encrypted);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-4-all-combined-to-bmp-05-k",children:"Task no. 4: All combined to BMP (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Authors of the BMP cipher are non-disclosed :)"}),"\n",(0,s.jsx)(n.p,{children:"Create pair of functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bmp_encrypt(const char* key, const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bmp_decrypt(const char* key, const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"BMP cipher consists of following steps for encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Reverse the input string"}),"\n",(0,s.jsx)(n.li,{children:"Use Vigenere on the string you got from step #1"}),"\n",(0,s.jsx)(n.li,{children:"Use bit madness on the string you got from step #2"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For decrypting, reverse the steps."}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function a(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>c});var s=r(67294);const t={},i=s.createContext(t);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.5d53fbfc.js b/assets/js/main.237fcc8a.js similarity index 78% rename from assets/js/main.5d53fbfc.js rename to assets/js/main.237fcc8a.js index ea46cc2..e2f4022 100644 --- a/assets/js/main.5d53fbfc.js +++ b/assets/js/main.237fcc8a.js @@ -1,2 +1,2 @@ -/*! For license information please see main.5d53fbfc.js.LICENSE.txt */ -(self.webpackChunkfi=self.webpackChunkfi||[]).push([[179],{20830:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});var r=n(67294);function a(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(67294);var r=n(68356),a=n.n(r),o=n(16887);const i={"0123bc76":[()=>n.e(3734).then(n.t.bind(n,76554,19)),"~docs/algorithms/tag-algorithms-tags-c-e22.json",76554],"0178f9ad":[()=>n.e(9898).then(n.bind(n,35610)),"@site/algorithms/08-rb-trees/2022-04-05-applications.md",35610],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,24524)),"@theme/BlogTagsListPage",24524],"0220f5fc":[()=>n.e(1378).then(n.t.bind(n,85804,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-blog/blog/plugin-route-context-module-100.json",85804],"0608d96f":[()=>n.e(7568).then(n.t.bind(n,77158,19)),"~blog/blog/blog-tags-vps-843-list.json",77158],"06c4a8fc":[()=>n.e(2125).then(n.t.bind(n,4697,19)),"~docs/algorithms/tag-algorithms-tags-testing-0c4.json",4697],"0816068a":[()=>n.e(2948).then(n.t.bind(n,17702,19)),"~blog/blog/blog-tags-hype-1ee.json",17702],"087808f1":[()=>n.e(3731).then(n.bind(n,48157)),"@site/algorithms/12-hash-tables/2023-11-28-breaking/index.md",48157],"08dfa3a2":[()=>n.e(2606).then(n.t.bind(n,32412,19)),"~docs/algorithms/tag-algorithms-tags-astar-f6e.json",32412],"0bfe45d5":[()=>n.e(4269).then(n.t.bind(n,13847,19)),"~blog/blog/blog-tags-rust-0c9-list.json",13847],"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(9365),n.e(7918)]).then(n.bind(n,15154)),"@theme/DocItem",15154],"182b5a8d":[()=>n.e(6048).then(n.bind(n,32582)),"@site/blog/2024-01-28-rust-opinion.md?truncated=true",32582],"19d7c045":[()=>n.e(4637).then(n.t.bind(n,67772,19)),"~blog/blog/blog-tags-advent-of-code-49f.json",67772],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,48852)),"@theme/SearchPage",48852],"1a606400":[()=>n.e(494).then(n.t.bind(n,82400,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/algorithms/plugin-route-context-module-100.json",82400],"1acf65cc":[()=>n.e(8529).then(n.bind(n,34568)),"@site/c/pexam/b-garbage_collect.md",34568],"1cd58e77":[()=>n.e(1547).then(n.bind(n,32090)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/04-bottom-up-dp.md",32090],"22a175ec":[()=>Promise.all([n.e(532),n.e(6890)]).then(n.bind(n,40707)),"@site/src/pages/contributions.tsx",40707],"24fecc0a":[()=>n.e(3707).then(n.bind(n,69383)),"@site/algorithms/03-time-complexity/2021-03-31-extend.md",69383],"257fa000":[()=>n.e(9595).then(n.t.bind(n,35455,19)),"~blog/blog/blog-tags-cult-e97-list.json",35455],"28d80ff8":[()=>n.e(6435).then(n.t.bind(n,7465,19)),"~docs/algorithms/tag-algorithms-tags-sorting-d73.json",7465],29694455:[()=>n.e(3388).then(n.t.bind(n,39828,19)),"~blog/blog/blog-tags-iterators-977-list.json",39828],"2af5d0a7":[()=>n.e(3979).then(n.t.bind(n,53703,19)),"~docs/algorithms/tag-algorithms-tags-a-star-775.json",53703],"2b89902a":[()=>n.e(6342).then(n.t.bind(n,45443,19)),"~docs/algorithms/tag-algorithms-tags-recursion-1bd.json",45443],"2ca64e35":[()=>n.e(281).then(n.bind(n,99544)),"@site/algorithms/04-recursion/2022-11-29-karel/index.md",99544],"2fcf0558":[()=>n.e(4638).then(n.t.bind(n,69470,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-hash-tables-062.json",69470],"3011a4c0":[()=>n.e(7926).then(n.t.bind(n,31670,19)),"~blog/blog/blog-tags-copr-70b-list.json",31670],30814625:[()=>n.e(115).then(n.bind(n,78416)),"@site/algorithms/04-recursion/2022-11-29-karel/2023-12-24-solution.md",78416],"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],"3adcbc3a":[()=>n.e(5701).then(n.bind(n,62535)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/01-bf.md",62535],"3d92ba6e":[()=>n.e(8236).then(n.t.bind(n,77778,19)),"~docs/algorithms/tag-algorithms-tags-dijkstra-48e.json",77778],"3da4b779":[()=>n.e(2177).then(n.bind(n,28737)),"@site/blog/aoc-2022/04-week-4.md",28737],"4200b1a9":[()=>n.e(866).then(n.t.bind(n,24612,19)),"~blog/blog/blog-archive-80c.json",24612],"45c9e308":[()=>n.e(7084).then(n.bind(n,53181)),"@site/cpp/07-exceptions-and-raii/2023-11-24-placeholders.md",53181],"4621632b":[()=>n.e(3519).then(n.t.bind(n,29760,19)),"~blog/blog/blog-tags-cpp-7c7-list.json",29760],"48b268a6":[()=>n.e(1648).then(n.t.bind(n,35067,19)),"~docs/c/category-c-autogeneratedbar-category-bonuses-216.json",35067],"493c0536":[()=>n.e(7292).then(n.bind(n,45594)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/03-astar.md",45594],"4e546705":[()=>n.e(4327).then(n.t.bind(n,61795,19)),"~docs/c/version-current-metadata-prop-751.json",61795],"4edd2021":[()=>n.e(5975).then(n.t.bind(n,21705,19)),"~blog/blog/blog-tags-cpp-7c7.json",21705],"4f96b16e":[()=>n.e(6306).then(n.bind(n,24693)),"@site/c/pexam/c-cams.md",24693],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],"5c15401e":[()=>n.e(9579).then(n.t.bind(n,43761,19)),"~docs/algorithms/tag-algorithms-tags-bellman-ford-731.json",43761],"5ca803d2":[()=>n.e(9173).then(n.t.bind(n,24890,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/c/plugin-route-context-module-100.json",24890],"5e95c892":[()=>n.e(9661).then(n.bind(n,41892)),"@theme/DocsRoot",41892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,36809)),"@generated/docusaurus.config",36809],"62d847b3":[()=>n.e(8520).then(n.t.bind(n,91901,19)),"~blog/blog/blog-tags-advent-of-code-2022-3db-list.json",91901],"66d5ef6c":[()=>n.e(9228).then(n.t.bind(n,4087,19)),"~blog/blog/blog-tags-tags-4c2.json",4087],"686a7a89":[()=>n.e(728).then(n.t.bind(n,77507,19)),"~docs/algorithms/tag-algorithms-tags-graphs-31d.json",77507],"6875c492":[()=>Promise.all([n.e(532),n.e(9365),n.e(130),n.e(8610)]).then(n.bind(n,41714)),"@theme/BlogTagsPostsPage",41714],"698e2076":[()=>n.e(3713).then(n.bind(n,38961)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/02-dijkstra.md",38961],"6bc697d0":[()=>n.e(5287).then(n.t.bind(n,68529,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/cpp/plugin-route-context-module-100.json",68529],"6e3cbca1":[()=>n.e(3276).then(n.t.bind(n,29538,19)),"~docs/algorithms/version-current-metadata-prop-751.json",29538],"7052c0bc":[()=>n.e(9731).then(n.bind(n,42286)),"@site/cpp/00-intro.md",42286],"70a4540f":[()=>n.e(9249).then(n.bind(n,44493)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/01-naive.md",44493],"75cccf44":[()=>n.e(4256).then(n.bind(n,98215)),"@site/blog/leetcode/sort-matrix-diagonally.md?truncated=true",98215],"765ea78b":[()=>n.e(3039).then(n.t.bind(n,83010,19)),"~blog/blog/blog-tags-\ud83c\udfed-551.json",83010],"794ef108":[()=>n.e(3803).then(n.bind(n,86427)),"@site/c/00-intro.md",86427],"7a5bb070":[()=>n.e(4582).then(n.t.bind(n,64863,19)),"~blog/blog/blog-tags-memory-safety-1ae.json",64863],"7ce7faac":[()=>n.e(6064).then(n.t.bind(n,12884,19)),"~docs/algorithms/tag-algorithms-tags-solution-61b.json",12884],"7e6d325b":[()=>n.e(3184).then(n.t.bind(n,26139,19)),"~docs/cpp/version-current-metadata-prop-751.json",26139],"84d1e0d8":[()=>n.e(1885).then(n.bind(n,49713)),"@site/algorithms/00-intro.md",49713],"86cd1460":[()=>n.e(1235).then(n.t.bind(n,38968,19)),"~blog/blog/blog-tags-leetcode-042.json",38968],"8a25f659":[()=>n.e(7728).then(n.bind(n,73212)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/03-top-down-dp.md",73212],"8b1802c5":[()=>n.e(8480).then(n.t.bind(n,60832,19)),"~blog/blog/blog-tags-advent-of-code-49f-list.json",60832],"8c0e532b":[()=>n.e(822).then(n.t.bind(n,73968,19)),"~blog/blog/blog-tags-vps-843.json",73968],"8d31a880":[()=>n.e(9066).then(n.t.bind(n,72232,19)),"~docs/algorithms/tag-algorithms-tags-python-48f.json",72232],"8e6bb954":[()=>n.e(5775).then(n.t.bind(n,76206,19)),"~docs/algorithms/tag-algorithms-tags-exponential-60a.json",76206],"9287eafd":[()=>n.e(5521).then(n.t.bind(n,90716,19)),"~blog/blog/blog-tags-rust-0c9.json",90716],"933b95b3":[()=>n.e(3887).then(n.t.bind(n,7405,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-recursion-257.json",7405],"947341b7":[()=>n.e(1145).then(n.t.bind(n,2897,19)),"~docs/algorithms/tag-algorithms-tags-bfs-69f.json",2897],"95b96bb9":[()=>n.e(3561).then(n.t.bind(n,24577,19)),"~blog/blog/blog-post-list-prop-blog.json",24577],"95f41f0b":[()=>n.e(9385).then(n.bind(n,93195)),"@site/blog/aoc-2022/01-week-1.md?truncated=true",93195],"962da50c":[()=>n.e(2264).then(n.t.bind(n,9705,19)),"~docs/c/category-c-autogeneratedbar-category-practice-exams-e97.json",9705],"976c4f3b":[()=>n.e(4562).then(n.t.bind(n,69019,19)),"~docs/algorithms/tag-algorithms-tags-java-6c3.json",69019],"97a42631":[()=>n.e(1464).then(n.t.bind(n,77343,19)),"~docs/algorithms/tags-list-current-prop-15a.json",77343],"9a3dc578":[()=>n.e(655).then(n.t.bind(n,9916,19)),"~docs/algorithms/tag-algorithms-tags-dynamic-array-5d3.json",9916],"9b91a88c":[()=>n.e(2545).then(n.bind(n,19466)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/index.md",19466],"9df0e937":[()=>n.e(2210).then(n.t.bind(n,55256,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-graphs-2e2.json",55256],"9e4087bc":[()=>n.e(3608).then(n.bind(n,63169)),"@theme/BlogArchivePage",63169],a082abd3:[()=>n.e(8786).then(n.t.bind(n,73276,19)),"~blog/blog/blog-tags-admin-b05.json",73276],a2ba8888:[()=>n.e(8289).then(n.t.bind(n,55941,19)),"~docs/algorithms/tag-algorithms-tags-brute-force-3cb.json",55941],a4c10cf4:[()=>n.e(4382).then(n.t.bind(n,30685,19)),"~docs/algorithms/tag-algorithms-tags-time-complexity-c50.json",30685],a6a48ea2:[()=>n.e(3618).then(n.bind(n,1176)),"@site/blog/aoc-2022/02-week-2.md?truncated=true",1176],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(9365),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],c4c4056e:[()=>n.e(635).then(n.bind(n,61381)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/index.md",61381],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,53261)),"@site/src/pages/index.js",53261],c580b66a:[()=>n.e(6573).then(n.t.bind(n,45021,19)),"~docs/algorithms/tag-algorithms-tags-top-down-dp-c2f.json",45021],c90b7ff3:[()=>n.e(3602).then(n.t.bind(n,44960,19)),"~blog/blog/blog-tags-hype-1ee-list.json",44960],ccc49370:[()=>Promise.all([n.e(532),n.e(9365),n.e(130),n.e(6103)]).then(n.bind(n,65203)),"@theme/BlogPostPage",65203],cfa2b263:[()=>n.e(3086).then(n.bind(n,34437)),"@site/blog/leetcode/sort-matrix-diagonally.md",34437],d05e838c:[()=>n.e(6544).then(n.bind(n,63004)),"@site/c/bonuses/05-06.md",63004],d255bd7f:[()=>n.e(6292).then(n.t.bind(n,60341,19)),"~docs/algorithms/tag-algorithms-tags-red-black-trees-c61.json",60341],d309b5b1:[()=>n.e(8908).then(n.t.bind(n,26102,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-algorithms-and-correctness-d51.json",26102],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],df078f58:[()=>n.e(7743).then(n.t.bind(n,88298,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-paths-in-graphs-202.json",88298],df0885f0:[()=>n.e(4343).then(n.t.bind(n,34175,19)),"~docs/algorithms/tag-algorithms-tags-iterators-13a.json",34175],df203c0f:[()=>Promise.all([n.e(532),n.e(9924)]).then(n.bind(n,40491)),"@theme/DocTagDocListPage",40491],dff2ebad:[()=>n.e(146).then(n.bind(n,42492)),"@site/blog/aoc-2022/01-week-1.md",42492],e1d2ae23:[()=>n.e(1475).then(n.t.bind(n,36302,19)),"~docs/algorithms/tag-algorithms-tags-applications-020.json",36302],e31003e9:[()=>n.e(1960).then(n.t.bind(n,81695,19)),"~docs/cpp/category-cpp-autogeneratedbar-category-exceptions-and-raii-6e9.json",81695],e89da83e:[()=>n.e(8757).then(n.t.bind(n,97416,19)),"~blog/blog/blog-tags-leetcode-042-list.json",97416],eba2374c:[()=>n.e(8387).then(n.t.bind(n,47662,19)),"~docs/algorithms/tag-algorithms-tags-backtracking-bb2.json",47662],f44abc07:[()=>n.e(2204).then(n.t.bind(n,39006,19)),"~blog/blog/blog-tags-cult-e97.json",39006],f48be158:[()=>n.e(4064).then(n.bind(n,12326)),"@site/blog/aoc-2022/03-week-3.md",12326],f71d1f68:[()=>n.e(6069).then(n.bind(n,13068)),"@site/blog/2024-01-28-rust-opinion.md",13068],f75910c4:[()=>n.e(5934).then(n.bind(n,1910)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/02-greedy.md",1910],f7d29e9b:[()=>n.e(7959).then(n.t.bind(n,89266,19)),"~blog/blog/blog-tags-memory-safety-1ae-list.json",89266],fb4361d3:[()=>n.e(6327).then(n.t.bind(n,9631,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-red-black-trees-d8a.json",9631],ff472cd9:[()=>n.e(8643).then(n.t.bind(n,7122,19)),"~blog/blog/blog-tags-iterators-977.json",7122],ff82dde7:[()=>Promise.all([n.e(532),n.e(8472)]).then(n.bind(n,63935)),"@site/algorithms/08-rb-trees/2023-06-10-rules.md",63935]};var s=n(85893);function l(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(99670),u=n(30226);function d(e,t){if("*"===e)return a()({loading:l,loader:()=>n.e(1772).then(n.bind(n,51772)),modules:["@theme/NotFound"],webpack:()=>[51772],render(e,t){const n=e.default;return(0,s.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},p=[],f=[],g=(0,c.Z)(r);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),a().Map({loading:l,loader:d,modules:p,webpack:()=>f,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let i=a;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=o}));const o=a.__comp;delete a.__comp;const i=a.__context;return delete a.__context,(0,s.jsx)(u.z,{value:i,children:(0,s.jsx)(o,{...a,...n})})}})}const p=[{path:"/blog/",component:d("/blog/","892"),exact:!0},{path:"/blog/2023/08/02/copr/",component:d("/blog/2023/08/02/copr/","69d"),exact:!0},{path:"/blog/2024/01/28/rust-opinion/",component:d("/blog/2024/01/28/rust-opinion/","98d"),exact:!0},{path:"/blog/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/cult/",component:d("/blog/tags/cult/","73d"),exact:!0},{path:"/blog/tags/hype/",component:d("/blog/tags/hype/","d35"),exact:!0},{path:"/blog/tags/iterators/",component:d("/blog/tags/iterators/","2eb"),exact:!0},{path:"/blog/tags/leetcode/",component:d("/blog/tags/leetcode/","e31"),exact:!0},{path:"/blog/tags/memory-safety/",component:d("/blog/tags/memory-safety/","d15"),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/","bfd"),exact:!0},{path:"/blog/tags/vps/",component:d("/blog/tags/vps/","1b8"),exact:!0},{path:"/contributions/",component:d("/contributions/","541"),exact:!0},{path:"/search/",component:d("/search/","c7b"),exact:!0},{path:"/talks/",component:d("/talks/","819"),exact:!0},{path:"/algorithms/",component:d("/algorithms/","c61"),routes:[{path:"/algorithms/",component:d("/algorithms/","b39"),routes:[{path:"/algorithms/tags/",component:d("/algorithms/tags/","bb8"),exact:!0},{path:"/algorithms/tags/a-star/",component:d("/algorithms/tags/a-star/","83e"),exact:!0},{path:"/algorithms/tags/applications/",component:d("/algorithms/tags/applications/","b32"),exact:!0},{path:"/algorithms/tags/astar/",component:d("/algorithms/tags/astar/","08b"),exact:!0},{path:"/algorithms/tags/backtracking/",component:d("/algorithms/tags/backtracking/","e2d"),exact:!0},{path:"/algorithms/tags/balanced-trees/",component:d("/algorithms/tags/balanced-trees/","591"),exact:!0},{path:"/algorithms/tags/bellman-ford/",component:d("/algorithms/tags/bellman-ford/","2bc"),exact:!0},{path:"/algorithms/tags/bfs/",component:d("/algorithms/tags/bfs/","334"),exact:!0},{path:"/algorithms/tags/bottom-up-dp/",component:d("/algorithms/tags/bottom-up-dp/","9e5"),exact:!0},{path:"/algorithms/tags/brute-force/",component:d("/algorithms/tags/brute-force/","99b"),exact:!0},{path:"/algorithms/tags/c/",component:d("/algorithms/tags/c/","cc5"),exact:!0},{path:"/algorithms/tags/cpp/",component:d("/algorithms/tags/cpp/","f5b"),exact:!0},{path:"/algorithms/tags/csharp/",component:d("/algorithms/tags/csharp/","7a9"),exact:!0},{path:"/algorithms/tags/dijkstra/",component:d("/algorithms/tags/dijkstra/","aa8"),exact:!0},{path:"/algorithms/tags/dynamic-array/",component:d("/algorithms/tags/dynamic-array/","00e"),exact:!0},{path:"/algorithms/tags/dynamic-programming/",component:d("/algorithms/tags/dynamic-programming/","f82"),exact:!0},{path:"/algorithms/tags/exponential/",component:d("/algorithms/tags/exponential/","a74"),exact:!0},{path:"/algorithms/tags/graphs/",component:d("/algorithms/tags/graphs/","d5b"),exact:!0},{path:"/algorithms/tags/greedy/",component:d("/algorithms/tags/greedy/","079"),exact:!0},{path:"/algorithms/tags/hash-tables/",component:d("/algorithms/tags/hash-tables/","ae4"),exact:!0},{path:"/algorithms/tags/iterative/",component:d("/algorithms/tags/iterative/","783"),exact:!0},{path:"/algorithms/tags/iterators/",component:d("/algorithms/tags/iterators/","1bc"),exact:!0},{path:"/algorithms/tags/java/",component:d("/algorithms/tags/java/","2b4"),exact:!0},{path:"/algorithms/tags/karel/",component:d("/algorithms/tags/karel/","79f"),exact:!0},{path:"/algorithms/tags/postconditions/",component:d("/algorithms/tags/postconditions/","a27"),exact:!0},{path:"/algorithms/tags/python/",component:d("/algorithms/tags/python/","eb2"),exact:!0},{path:"/algorithms/tags/recursion/",component:d("/algorithms/tags/recursion/","2b0"),exact:!0},{path:"/algorithms/tags/red-black-trees/",component:d("/algorithms/tags/red-black-trees/","9ca"),exact:!0},{path:"/algorithms/tags/solution/",component:d("/algorithms/tags/solution/","fa0"),exact:!0},{path:"/algorithms/tags/sorting/",component:d("/algorithms/tags/sorting/","7ca"),exact:!0},{path:"/algorithms/tags/testing/",component:d("/algorithms/tags/testing/","2af"),exact:!0},{path:"/algorithms/tags/time-complexity/",component:d("/algorithms/tags/time-complexity/","2d3"),exact:!0},{path:"/algorithms/tags/top-down-dp/",component:d("/algorithms/tags/top-down-dp/","779"),exact:!0},{path:"/algorithms/",component:d("/algorithms/","b7c"),routes:[{path:"/algorithms/",component:d("/algorithms/","9b0"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/algorithms-correctness/postcondition-ambiguity/",component:d("/algorithms/algorithms-correctness/postcondition-ambiguity/","c18"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/algorithms-and-correctness/",component:d("/algorithms/category/algorithms-and-correctness/","ea2"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/asymptotic-notation-and-time-complexity/",component:d("/algorithms/category/asymptotic-notation-and-time-complexity/","fba"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/graphs/",component:d("/algorithms/category/graphs/","a92"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/hash-tables/",component:d("/algorithms/category/hash-tables/","ddd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/paths-in-graphs/",component:d("/algorithms/category/paths-in-graphs/","7c7"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/recursion/",component:d("/algorithms/category/recursion/","61f"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/red-black-trees/",component:d("/algorithms/category/red-black-trees/","0c0"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/graphs/bfs-tree/",component:d("/algorithms/graphs/bfs-tree/","2fb"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/graphs/iterative-and-iterators/",component:d("/algorithms/graphs/iterative-and-iterators/","bfd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/",component:d("/algorithms/hash-tables/breaking/","319"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/mitigations/",component:d("/algorithms/hash-tables/breaking/mitigations/","4c2"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/python/",component:d("/algorithms/hash-tables/breaking/python/","3d1"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/",component:d("/algorithms/paths/bf-to-astar/","050"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/astar/",component:d("/algorithms/paths/bf-to-astar/astar/","b4d"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/bf/",component:d("/algorithms/paths/bf-to-astar/bf/","e9c"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/dijkstra/",component:d("/algorithms/paths/bf-to-astar/dijkstra/","fe4"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/rb-trees/applications/",component:d("/algorithms/rb-trees/applications/","46a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/rb-trees/rules/",component:d("/algorithms/rb-trees/rules/","21a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/karel/",component:d("/algorithms/recursion/karel/","4cf"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/karel/solution/",component:d("/algorithms/recursion/karel/solution/","115"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/",component:d("/algorithms/recursion/pyramid-slide-down/","236"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/bottom-up-dp/",component:d("/algorithms/recursion/pyramid-slide-down/bottom-up-dp/","00d"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/greedy/",component:d("/algorithms/recursion/pyramid-slide-down/greedy/","4bf"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/naive/",component:d("/algorithms/recursion/pyramid-slide-down/naive/","c1b"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/top-down-dp/",component:d("/algorithms/recursion/pyramid-slide-down/top-down-dp/","fe9"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/time-complexity/extend/",component:d("/algorithms/time-complexity/extend/","250"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/c/",component:d("/c/","dae"),routes:[{path:"/c/",component:d("/c/","fc8"),routes:[{path:"/c/",component:d("/c/","1c4"),routes:[{path:"/c/",component:d("/c/","a0f"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-03/",component:d("/c/bonuses/seminar-03/","aaa"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-04/",component:d("/c/bonuses/seminar-04/","ffe"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-05-06/",component:d("/c/bonuses/seminar-05-06/","4cd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-08/",component:d("/c/bonuses/seminar-08/","09a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-10/",component:d("/c/bonuses/seminar-10/","b9e"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/category/bonuses/",component:d("/c/category/bonuses/","17e"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/category/practice-exams/",component:d("/c/category/practice-exams/","009"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/mr/",component:d("/c/mr/","4c5"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/pexam/cams/",component:d("/c/pexam/cams/","a10"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/pexam/garbage_collect/",component:d("/c/pexam/garbage_collect/","44e"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/cpp/",component:d("/cpp/","269"),routes:[{path:"/cpp/",component:d("/cpp/","187"),routes:[{path:"/cpp/",component:d("/cpp/","102"),routes:[{path:"/cpp/",component:d("/cpp/","fcd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/category/exceptions-and-raii/",component:d("/cpp/category/exceptions-and-raii/","cfa"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/environment/",component:d("/cpp/environment/","e0b"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/exceptions-and-raii/placeholders/",component:d("/cpp/exceptions-and-raii/placeholders/","9b3"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/",component:d("/","dfb"),exact:!0},{path:"*",component:d("*")}]},98934:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>i});var r=n(67294),a=n(85893);const o=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,a.jsx)(o.Provider,{value:n,children:t})}},97221:(e,t,n)=>{"use strict";var r=n(67294),a=n(20745),o=n(73727),i=n(70405),s=n(10412);const l=[n(32497),n(3310),n(18320),n(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 j=n(98934),N=n(58940),L=n(20469);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const I=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 R(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 O 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}),R(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)(I,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const F=O,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),R(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)}))}};R(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},"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},"algorithms":{"path":"/algorithms","versions":[{"name":"current","label":"Next","isLast":true,"path":"/algorithms","mainDocId":"algorithms-intro","docs":[{"id":"algorithms-correctness/postcondition-ambiguity","path":"/algorithms/algorithms-correctness/postcondition-ambiguity","sidebar":"autogeneratedBar"},{"id":"algorithms-intro","path":"/algorithms/","sidebar":"autogeneratedBar"},{"id":"graphs/bfs-tree","path":"/algorithms/graphs/bfs-tree","sidebar":"autogeneratedBar"},{"id":"graphs/iterative-and-iterators","path":"/algorithms/graphs/iterative-and-iterators","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/breaking","path":"/algorithms/hash-tables/breaking","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/mitigations","path":"/algorithms/hash-tables/breaking/mitigations","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/python","path":"/algorithms/hash-tables/breaking/python","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/astar","path":"/algorithms/paths/bf-to-astar/astar","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/bf","path":"/algorithms/paths/bf-to-astar/bf","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/dijkstra","path":"/algorithms/paths/bf-to-astar/dijkstra","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/index","path":"/algorithms/paths/bf-to-astar","sidebar":"autogeneratedBar"},{"id":"rb-trees/applications","path":"/algorithms/rb-trees/applications","sidebar":"autogeneratedBar"},{"id":"rb-trees/rules","path":"/algorithms/rb-trees/rules","sidebar":"autogeneratedBar"},{"id":"recursion/2022-11-29-karel/karel","path":"/algorithms/recursion/karel","sidebar":"autogeneratedBar"},{"id":"recursion/2022-11-29-karel/solution","path":"/algorithms/recursion/karel/solution","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","path":"/algorithms/recursion/pyramid-slide-down/bottom-up-dp","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/greedy","path":"/algorithms/recursion/pyramid-slide-down/greedy","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/naive","path":"/algorithms/recursion/pyramid-slide-down/naive","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","path":"/algorithms/recursion/pyramid-slide-down","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","path":"/algorithms/recursion/pyramid-slide-down/top-down-dp","sidebar":"autogeneratedBar"},{"id":"time-complexity/extend","path":"/algorithms/time-complexity/extend","sidebar":"autogeneratedBar"},{"id":"/category/algorithms-and-correctness","path":"/algorithms/category/algorithms-and-correctness","sidebar":"autogeneratedBar"},{"id":"/category/asymptotic-notation-and-time-complexity","path":"/algorithms/category/asymptotic-notation-and-time-complexity","sidebar":"autogeneratedBar"},{"id":"/category/recursion","path":"/algorithms/category/recursion","sidebar":"autogeneratedBar"},{"id":"/category/red-black-trees","path":"/algorithms/category/red-black-trees","sidebar":"autogeneratedBar"},{"id":"/category/graphs","path":"/algorithms/category/graphs","sidebar":"autogeneratedBar"},{"id":"/category/paths-in-graphs","path":"/algorithms/category/paths-in-graphs","sidebar":"autogeneratedBar"},{"id":"/category/hash-tables","path":"/algorithms/category/hash-tables","sidebar":"autogeneratedBar"}],"draftIds":[],"sidebars":{"autogeneratedBar":{"link":{"path":"/algorithms/","label":"algorithms-intro"}}}}],"breadcrumbs":true}}}'),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.1.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.1.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.1.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.1.1"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.1.1"},"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.1.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.1.1"},"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.1.1"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.1.1"}}}');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(80647),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})}},33692:(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(28138),u=n(44996),d=n(85893);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,u.C)(),x=(0,c.Z)(),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>S.current));const _=p||f;const E=(0,s.Z)(_),C=_?.replace("pathname://","");let T=void 0!==C?(A=C,b&&(e=>e.startsWith("/"))(A)?k(A):A):void 0;var A;T&&E&&(T=(0,o.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:w}));const j=(0,r.useRef)(!1),N=n?a.OL:a.rU,L=l.Z.canUseIntersectionObserver,P=(0,r.useRef)(),I=()=>{j.current||null==T||(window.docusaurus.preload(T),j.current=!0)};(0,r.useEffect)((()=>(!L&&E&&null!=T&&window.docusaurus.prefetch(T),()=>{L&&P.current&&P.current.disconnect()})),[P,T,L,E]);const R=T?.startsWith("#")??!1,O=!y.target||"_self"===y.target,F=!T||!E||!O||R;return m||!R&&F||x.collectLink(T),y.id&&x.collectAnchor(y.id),F?(0,d.jsx)("a",{ref:S,href:T,..._&&!E&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,d.jsx)(N,{...y,onMouseEnter:I,onTouchStart:I,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)}},28138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(67294);n(85893);const a=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),o=()=>(0,r.useContext)(a);function i(){return o()}},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:()=>u});n(67294);var r=n(36905),a=n(95999),o=n(86668),i=n(33692),s=n(28138);const l={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var c=n(85893);function u(e){let{as:t,id:n,...u}=e;const d=(0,s.Z)(),{navbar:{hideOnScroll:p}}=(0,o.L)();if("h1"===t||!n)return(0,c.jsx)(t,{...u,id:void 0});d.collectAnchor(n);const f=(0,a.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,c.jsxs)(t,{...u,className:(0,r.Z)("anchor",p?l.anchorWithHideOnScrollNavbar:l.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,c.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,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"})})}},80647:(e,t,n)=>{"use strict";n.d(t,{Z:()=>At});var r=n(67294),a=n(36905),o=n(44763),i=n(10833),s=n(16550),l=n(95999),c=n(85936),u=n(85893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??g,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var m=n(35281),b=n(19727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(h,{className:y.skipToContent})}var w=n(86668),k=n(59689);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:a=1.2,className:o,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:a,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function _(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.Z)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,a.Z)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:r,textColor:a,isCloseable:o}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:a},role:"banner",children:[o&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(C,{className:T.announcementBarContent}),o&&(0,u.jsx)(_,{onClick:n,className:T.announcementBarClose})]})}var j=n(93163),N=n(12466);var L=n(902),P=n(13102);const I=r.createContext(null);function R(e){let{children:t}=e;const n=function(){const e=(0,j.e)(),t=(0,P.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,L.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return(0,u.jsx)(I.Provider,{value:n,children:t})}function O(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function F(){const e=(0,r.useContext)(I);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:O(o)})),[a,o,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:o}=F();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var D=n(92949),B=n(72389);function z(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Z(e){let{className:t,buttonClassName:n,value:r,onChange:o}=e;const i=(0,B.Z)(),s=(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,a.Z)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,a.Z)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>o("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,u.jsx)(z,{className:(0,a.Z)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,a.Z)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=r.memo(Z),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,D.I)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:a,onChange:o})}var G=n(21327);function q(){return(0,u.jsx)(G.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,j.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(q,{}),(0,u.jsx)(W,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Q=n(33692),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);const ce={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(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 de(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)(He,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(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=ue(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)(ce.dropdownNavbarItemMobile,"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)(He,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:de;return(0,u.jsx)(r,{...n})}var ge=n(94711);function he(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 me="iconLanguage_nlXk";var be=n(73935);function ye(){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 ve=n(20830),we=["translations"];function ke(){return ke=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 Ee="Ctrl";var Ce=r.forwardRef((function(e,t){var n=e.translations,a=void 0===n?{}:n,o=_e(e,we),i=a.buttonText,s=void 0===i?"Search":i,l=a.buttonAriaLabel,c=void 0===l?"Search":l,u=xe((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(Ee))}),[]),r.createElement("button",ke({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},o,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(ve.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===Ee?r.createElement(ye,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Te=n(35742),Ae=n(66177),je=n(239),Ne=n(43320);const Le={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 Pe=null;function Ie(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,Ae.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,je.l)(),c=function(){const{locale:e,tags:t}=(0,Ne._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)((()=>Pe?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;Pe=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)(Te.Z,{children:(0,u.jsx)("link",{rel:"preconnect",href:`https://${o.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,u.jsx)(Ce,{onTouchStart:k,onFocus:k,onMouseOver:k,onClick:x,ref:m,translations:Le.button}),b&&Pe&&h.current&&(0,be.createPortal)((0,u.jsx)(Pe,{onClose:S,initialScrollY:window.scrollY,initialQuery:v,navigator:E,transformItems:C,hitComponent:Ie,transformSearchClient:A,...o.searchPagePath&&{resultsFooterComponent:T},...o,searchParameters:f,placeholder:Le.placeholder,translations:Le.modal}),h.current)]})}function Fe(){const{siteConfig:e}=(0,le.Z)();return(0,u.jsx)(Oe,{...e.themeConfig.algolia})}const Me={navbarSearchContainer:"navbarSearchContainer_Bca1"};function De(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,a.Z)(n,Me.navbarSearchContainer),children:t})}var Be=n(80143),ze=n(53438);var $e=n(60373);const Ue=e=>e.docs.find((t=>t.id===e.mainDocId));const Ze={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,ge.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)(fe,{...o,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(he,{className:me}),m]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(De,{className:n,children:(0,u.jsx)(Fe,{})})},dropdown:fe,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,Be.Iw)(r),i=(0,ze.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,Be.Iw)(r),i=(0,ze.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,ze.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,Be.Iw)(n),f=(0,Be.gB)(n),{savePreferredVersionName:g}=(0,$e.J)(n),h=[...a,...f.map((e=>{const t=p.alternateDocVersions[e.name]??Ue(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...o],m=(0,ze.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:Ue(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)(fe,{...i,mobile:t,label:b,to:y,items:h,isActive:r?()=>!1:void 0})}};function He(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=Ze[r];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(a,{...n})}function Ve(){const e=(0,j.e)(),t=(0,w.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(He,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function We(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 Ge(){const e=0===(0,w.L)().navbar.items.length,t=F();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(We,{onClick:()=>t.hide()}),t.content]})}function qe(){const e=(0,j.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(M,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(Ve,{}),secondaryMenu:(0,u.jsx)(Ge,{})}):null}const Ke={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ye(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,a.Z)("navbar-sidebar__backdrop",e.className)})}function Qe(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,j.e)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,N.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Ke.navbarHideable,!d&&Ke.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ye,{onClick:i.toggle}),(0,u.jsx)(qe,{})]})}var Xe=n(69690);const Je="right";function et(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 tt(){const{toggle:e,shown:t}=(0,j.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(et,{})})}const nt={colorModeToggle:"colorModeToggle_DEke"};function rt(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Xe.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)(He,{...e})},t)))})}function at(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 ot(){const e=(0,j.e)(),t=(0,w.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Je)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return(0,u.jsx)(at,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(tt,{}),(0,u.jsx)(q,{}),(0,u.jsx)(rt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(rt,{items:r}),(0,u.jsx)(W,{className:nt.colorModeToggle}),!a&&(0,u.jsx)(De,{children:(0,u.jsx)(Fe,{})})]})})}function it(){return(0,u.jsx)(Qe,{children:(0,u.jsx)(ot,{})})}function st(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 lt(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)(st,{item:t})},t.href??t.to)}function ct(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)(lt,{item:e},t)))})]})}function ut(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(ct,{column:e},t)))})}function dt(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function pt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(st,{item:t})}function ft(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)(pt,{item:e}),t.length!==n+1&&(0,u.jsx)(dt,{})]},n)))})})}function gt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(ut,{columns:t}):(0,u.jsx)(ft,{links:t})}var ht=n(19965);const mt={footerLogoLink:"footerLogoLink_BH7S"};function bt(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)(ht.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function yt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Q.Z,{href:t.href,className:mt.footerLogoLink,target:t.target,children:(0,u.jsx)(bt,{logo:t})}):(0,u.jsx)(bt,{logo:t})}function vt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function wt(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 kt(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,u.jsx)(wt,{style:a,links:n&&n.length>0&&(0,u.jsx)(gt,{links:n}),logo:r&&(0,u.jsx)(yt,{logo:r}),copyright:t&&(0,u.jsx)(vt,{copyright:t})})}const xt=r.memo(kt),St=(0,L.Qc)([D.S,k.pl,N.OC,$e.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(P.n2,{children:(0,u.jsx)(j.M,{children:(0,u.jsx)(R,{children:t})})})}]);function _t(e){let{children:t}=e;return(0,u.jsx)(St,{children:t})}var Et=n(92503);function Ct(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)(Et.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)(Xe.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)(Xe.aG,{error:t})})]})})})}const Tt={mainWrapper:"mainWrapper_z2l0"};function At(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:l}=e;return(0,b.t)(),(0,u.jsxs)(_t,{children:[(0,u.jsx)(i.d,{title:s,description:l}),(0,u.jsx)(v,{}),(0,u.jsx)(A,{}),(0,u.jsx)(it,{}),(0,u.jsx)("div",{id:d,className:(0,a.Z)(m.k.wrapper.main,Tt.mainWrapper,r),children:(0,u.jsx)(o.Z,{fallback:e=>(0,u.jsx)(Ct,{...e}),children:t})}),!n&&(0,u.jsx)(xt,{})]})}},21327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(67294);var r=n(33692),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(788),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(e){let{desktopBreakpoint:t=i}=void 0===e?{}:e;const[n,s]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){s(function(e){if(!a.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?o.desktop:o.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},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!0}}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(788),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}})},99318:(e,t,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]),j=r(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[A]),2),N=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,L=t(/<<0>>(?:\s*\(<<1>>*\))?/.source,[b,j]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:n(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[N,L]),lookbehind:!0,greedy:!0,inside:{target:{pattern:n(/^<<0>>(?=\s*:)/.source,[N]),alias:"keyword"},"attribute-arguments":{pattern:n(/\(<<0>>*\)/.source,[j]),inside:e.languages.csharp},"class-name":{pattern:RegExp(b),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var P=/:[^}\r\n]+/.source,I=r(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[A]),2),R=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[I,P]),O=r(t(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source,[T]),2),F=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[O,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,[R]),lookbehind:!0,greedy:!0,inside:M(R,I)},{pattern:n(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[F]),lookbehind:!0,greedy:!0,inside:M(F,O)}],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

    Solution

    We need to “build” a file system from the input that is given in a following form:

    -
    $ cd /
    $ ls
    dir a
    14848514 b.txt
    8504156 c.dat
    dir d
    $ cd a
    $ ls
    dir e
    29116 f
    2557 g
    62596 h.lst
    $ cd e
    $ ls
    584 i
    $ cd ..
    $ cd ..
    $ cd d
    $ ls
    4060174 j
    8033020 d.log
    5626152 d.ext
    7214296 k
    +
    $ cd /
    $ ls
    dir a
    14848514 b.txt
    8504156 c.dat
    dir d
    $ cd a
    $ ls
    dir e
    29116 f
    2557 g
    62596 h.lst
    $ cd e
    $ ls
    584 i
    $ cd ..
    $ cd ..
    $ cd d
    $ ls
    4060174 j
    8033020 d.log
    5626152 d.ext
    7214296 k

    There are few ways in which you can achieve this and also you can assume some preconditions, but why would we do that, right? :)

    You can “slap” this in either HashMap or BTreeMap and call it a day. And that would be boring…

    tip

    BTreeMap is quite fitting for this, don't you think?

    I always wanted to try allocation on heap in Rust, so I chose to implement a tree. -I fought with the Box<T> for some time and was losing…

    +I fought with the Box<T> for some time and was losing…

    Then I looked up some implementations of trees or linked lists and decided to try Rc<Cell<T>>. And I got my ass whopped by the compiler once again. /o\

    tip

    Box<T> represents a dynamically allocated memory on heap. It is a single pointer, @@ -171,7 +171,7 @@ references are present) are checked dynamically.

    So in the end, if you wan to have Rc<RefCell<T>>.

    So, how are we going to represent the file system then? We will use an enumeration, hehe, which is an algebraic data type that can store some stuff in itself 😩

    -
    type FileHandle = Rc<RefCell<AocFile>>;

    #[derive(Debug)]
    enum AocFile {
    File(usize),
    Directory(BTreeMap<String, FileHandle>),
    }
    +
    type FileHandle = Rc<RefCell<AocFile>>;

    #[derive(Debug)]
    enum AocFile {
    File(usize),
    Directory(BTreeMap<String, FileHandle>),
    }

    Let's go over it! FileHandle represents dynamically allocated AocFile, not much to discuss. What does the #[derive(Debug)] do though? It lets us to print out the value of that enumeration, it's derived, so it's not as good as if we had diff --git a/blog/aoc-2022/2nd-week/index.html b/blog/aoc-2022/2nd-week/index.html index 6820257..c6ab6e4 100644 --- a/blog/aoc-2022/2nd-week/index.html +++ b/blog/aoc-2022/2nd-week/index.html @@ -14,8 +14,8 @@ - - + +

    2nd week of Advent of Code '22 in Rust

    · 21 min read
    Matej Focko

    Let's go through the second week of Advent of Code in Rust.

    @@ -39,7 +39,7 @@ own “box of hell”.

    Swapping indices

    Relatively simple implementation, just take the values, swap them and return new vector.

    -
    impl<T: Copy> Vector2D<T> {
    pub fn swap(&self) -> Self {
    Self {
    x: self.y,
    y: self.x,
    }
    }
    }
    +
    impl<T: Copy> Vector2D<T> {
    pub fn swap(&self) -> Self {
    Self {
    x: self.y,
    y: self.x,
    }
    }
    }

    Pretty straight-forward implementation, but let's talk about the T: Copy. We need to use it, since we are returning a new vector, with swapped values. If we had values that cannot be copied, the only thing we could do, would be a @@ -48,7 +48,7 @@ later on). This is pretty similar with the operations on sets from the first wee

    Indexing Vec

    I will start with the indexing, cause bound-checking is a bit more… complicated than I would like to.

    -
    pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }
    +
    pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }

    Let's talk about this mess… Body of the function is probably the most easy part and should not be hard to understand, we just take the x and y and convert them both to usize type that can be used later on for indexing.

    @@ -87,20 +87,20 @@ taken by a reference, i.e. returned reference must live at least as long as the

    First issue that our implementation has is the fact that we cannot get a mutable reference out of that function. This could be easily resolved by introducing new function, e.g. index_mut. Which I have actually done while writing this part:

    -
    pub fn index_mut<'a, T, U>(v: &'a mut [Vec<U>], idx: &Vector2D<T>) -> &'a mut U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &mut v[y][x]
    }
    +
    pub fn index_mut<'a, T, U>(v: &'a mut [Vec<U>], idx: &Vector2D<T>) -> &'a mut U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &mut v[y][x]
    }
    «↯» Why can't we use one function?

    When we consider a Vec<T>, we don't need to consider containers as T, Rust implements indexing as traits Index<T> and IndexMut<T> that do the dirty work behind syntactic sugar of container[idx].

    However, implementing of traits is not allowed for external types, i.e. types that you haven't defined yourself. This means that you can implement indexing over containers that you have implemented yourself, but you cannot use your own types for indexing “built-in” types.

    Another part of this rabbit hole is trait SliceIndex<T> that is of a relevance -because of

    impl<T, I> Index<I> for [T]
    where
    I: SliceIndex<[T]>

    impl<T, I, A> Index<I> for Vec<T, A>
    where
    I: SliceIndex<[T]>,
    A: Allocator

    impl<T, I, const N: usize> Index<I> for [T; N]
    where
    [T]: Index<I>

    In other words, if your type implements SliceIndex<T> trait, it can be used +because of

    impl<T, I> Index<I> for [T]
    where
    I: SliceIndex<[T]>

    impl<T, I, A> Index<I> for Vec<T, A>
    where
    I: SliceIndex<[T]>,
    A: Allocator

    impl<T, I, const N: usize> Index<I> for [T; N]
    where
    [T]: Index<I>

    In other words, if your type implements SliceIndex<T> trait, it can be used for indexing. As of now, this trait has all of its required methods experimental and is marked as unsafe.

    Another problem is a requirement for indexing either [Vec<T>] or Vec<Vec<T>>. This requirement could be countered by removing inner type Vec<T> and constraining it by a trait Index (or IndexMut respectively) in a following way

    -
    pub fn index<'a, C, T>(v: &'a [C], idx: &Vector2D<T>) -> &'a C::Output
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    C: Index<usize>
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }
    +
    pub fn index<'a, C, T>(v: &'a [C], idx: &Vector2D<T>) -> &'a C::Output
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    C: Index<usize>
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }

    Given this, we can also give a more meaningful typename for indexing type, such as I.

    Checking bounds

    @@ -111,12 +111,12 @@ up with negative values which, unlike in C++, causes an error (instead of underf that you can use to your advantage; you can easily guess how).

    So how can we approach this then? Well… we will convert the bounds instead of the indices and that lead us to:

    -
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    usize: TryInto<T>,
    <usize as TryInto<T>>::Error: Debug,
    T: PartialOrd + Copy,
    {
    idx.y >= 0.try_into().unwrap()
    && idx.y < v.len().try_into().unwrap()
    && idx.x >= 0.try_into().unwrap()
    && idx.x
    < v[TryInto::<usize>::try_into(idx.y).unwrap()]
    .len()
    .try_into()
    .unwrap()
    }
    +
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    usize: TryInto<T>,
    <usize as TryInto<T>>::Error: Debug,
    T: PartialOrd + Copy,
    {
    idx.y >= 0.try_into().unwrap()
    && idx.y < v.len().try_into().unwrap()
    && idx.x >= 0.try_into().unwrap()
    && idx.x
    < v[TryInto::<usize>::try_into(idx.y).unwrap()]
    .len()
    .try_into()
    .unwrap()
    }

    You can tell that it's definitely a shitty code. Let's improve it now! We will get back to the original idea, but do it better. We know that we cannot convert negative values into usize, but we also know that conversion like that returns a Result<T, E> which we can use to our advantage.

    -
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    T: Copy,
    usize: TryFrom<T>,
    {
    usize::try_from(idx.y)
    .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))
    .unwrap_or(false)
    }
    +
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    T: Copy,
    usize: TryFrom<T>,
    {
    usize::try_from(idx.y)
    .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))
    .unwrap_or(false)
    }

    Result<T, E> is a type similar to Either in Haskell and it allows us to chain multiple operations on correct results or propagate the original error without doing anything. Let's dissect it one-by-one.

    @@ -125,7 +125,7 @@ types and either successfully convert them or fail (with a reasonable error). Th method returns Result<T, E>.

    We call and_then on that result, let's have a look at the type signature of and_then, IMO it explains more than enough:

    -
    pub fn and_then<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> Result<U, E>
    +
    pub fn and_then<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> Result<U, E>

    OK… So it takes the result and a function and returns another result with different value and different error. However we can see that the function, which represents an operation on a result, takes just the value, i.e. it doesn't care @@ -135,7 +135,7 @@ about any previous error. To make it short:

    We parsed a y index and now we try to convert the x index with try_from again, but on that result we use map rather than and_then, why would that be?

    -
    pub fn map<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> U
    +
    pub fn map<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> U

    Huh… map performs an operation that cannot fail. And finally we use unwrap_or which takes the value from result, or in case of an error returns the default that we define.

    @@ -164,13 +164,13 @@ preparations for the AoC. Let's sum up our requirements:

    cannot do anything about it. However running and testing can be simplified!

    Let's introduce and export a new module solution that will take care of all of this. We will start by introducing a trait for each day.

    -
    pub trait Solution<Input, Output: Display> {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input;

    fn part_1(input: &Input) -> Output;
    fn part_2(input: &Input) -> Output;
    }
    +
    pub trait Solution<Input, Output: Display> {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input;

    fn part_1(input: &Input) -> Output;
    fn part_2(input: &Input) -> Output;
    }

    This does a lot of work for us already, we have defined a trait and for each day we will create a structure representing a specific day. That structure will also implement the Solution trait.

    Now we need to get rid of the boilerplate, we can't get rid of the main function, but we can at least move out the functionality.

    -
    fn run(type_of_input: &str) -> Result<()>
    where
    Self: Sized,
    {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = Self::parse_input(format!("{}s/{}.txt", type_of_input, Self::day()));

    info!("Part 1: {}", Self::part_1(&input));
    info!("Part 2: {}", Self::part_2(&input));

    Ok(())
    }

    fn main() -> Result<()>
    where
    Self: Sized,
    {
    Self::run("input")
    }
    +
    fn run(type_of_input: &str) -> Result<()>
    where
    Self: Sized,
    {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = Self::parse_input(format!("{}s/{}.txt", type_of_input, Self::day()));

    info!("Part 1: {}", Self::part_1(&input));
    info!("Part 2: {}", Self::part_2(&input));

    Ok(())
    }

    fn main() -> Result<()>
    where
    Self: Sized,
    {
    Self::run("input")
    }

    This is all part of the Solution trait, which can implement methods while being dependent on what is provided by the implementing types. In this case, we just need to bound the Output type to implement Display that is necessary for the @@ -179,14 +179,14 @@ need to bound the Output type to implement Display tha day() method that you can see being used when constructing path to the input file. That method will generate a name of the file, e.g. day01 and we know that we can somehow deduce it from the structure name, given we name it reasonably.

    -
    fn day() -> String {
    let mut day = String::from(type_name::<Self>().split("::").next().unwrap());
    day.make_ascii_lowercase();

    day.to_string()
    }
    +
    fn day() -> String {
    let mut day = String::from(type_name::<Self>().split("::").next().unwrap());
    day.make_ascii_lowercase();

    day.to_string()
    }
    type_name

    This feature is still experimental and considered to be internal, it is not advised to use it any production code.

    And now we can get to the nastiest stuff 😩 We will generate the tests!

    We want to be able to generate tests for sample input in a following way:

    -
    test_sample!(day_01, Day01, 42, 69);
    +
    test_sample!(day_01, Day01, 42, 69);

    There's not much we can do, so we will write a macro to generate the tests for us.

    -
    #[macro_export]
    macro_rules! test_sample {
    ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {
    #[cfg(test)]
    mod $mod_name {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_1(&sample), $part_1);
    }

    #[test]
    fn test_part_2() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_2(&sample), $part_2);
    }
    }
    };
    }
    +
    #[macro_export]
    macro_rules! test_sample {
    ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {
    #[cfg(test)]
    mod $mod_name {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_1(&sample), $part_1);
    }

    #[test]
    fn test_part_2() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_2(&sample), $part_2);
    }
    }
    };
    }

    We have used it in a similar way as macros in C/C++, one of the things that we can use to our advantage is defining “type” of the parameters for the macro. All parameters have their name prefixed with $ sign and you can define various “forms” @@ -202,7 +202,7 @@ which literally means an expression.

    Apart from that we need to use #[macro_export] to mark the macro as exported for usage outside of the module. Now our skeleton looks like:

    -
    use aoc_2022::*;

    type Input = String;
    type Output = String;

    struct DayXX;
    impl Solution<Input, Output> for DayXX {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
    file_to_string(pathname)
    }

    fn part_1(input: &Input) -> Output {
    todo!()
    }

    fn part_2(input: &Input) -> Output {
    todo!()
    }
    }

    fn main() -> Result<()> {
    // DayXX::run("sample")
    DayXX::main()
    }

    // test_sample!(day_XX, DayXX, , );
    +
    use aoc_2022::*;

    type Input = String;
    type Output = String;

    struct DayXX;
    impl Solution<Input, Output> for DayXX {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
    file_to_string(pathname)
    }

    fn part_1(input: &Input) -> Output {
    todo!()
    }

    fn part_2(input: &Input) -> Output {
    todo!()
    }
    }

    fn main() -> Result<()> {
    // DayXX::run("sample")
    DayXX::main()
    }

    // test_sample!(day_XX, DayXX, , );

    Solution

    Not much to talk about, it is relatively easy to simulate.

    Day 10: Cathode-Ray Tube

    @@ -212,7 +212,7 @@ CPU's accumulator.

    And the issue is caused by different types of Output for the part 1 and part 2.

    Problem is relatively simple and consists of simulating a CPU, I have approached it in a following way:

    -
    fn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {
    instructions
    .iter()
    .fold(State::new(), |state, instruction| {
    state.execute(instruction, &mut out)
    });

    out
    }
    +
    fn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {
    instructions
    .iter()
    .fold(State::new(), |state, instruction| {
    state.execute(instruction, &mut out)
    });

    out
    }

    We just take the instructions, we have some state of the CPU and we execute the instructions one-by-one. Perfect usage of the fold (or reduce as you may know it from other languages).

    @@ -220,11 +220,11 @@ it from other languages).

    that problem. And the answer is very simple and functional. Rust allows you to have an enumeration that can bear some other values apart from the type itself.

    tip

    We could've seen something like this with the Result<T, E> type that can be -defined as

    enum Result<T, E> {
    Ok(T),
    Err(E)
    }
    What does that mean though?

    When we have an Ok value, it has the result itself, and when we get an Err +defined as

    enum Result<T, E> {
    Ok(T),
    Err(E)
    }
    What does that mean though?

    When we have an Ok value, it has the result itself, and when we get an Err value, it has the error. This also allows us to handle results in a rather -pretty way:

    match do_something(x) {
    Ok(y) => {
    println!("SUCCESS: {}", y);
    },
    Err(y) => {
    eprintln!("ERROR: {}", y);
    }
    }
    +pretty way:

    match do_something(x) {
    Ok(y) => {
    println!("SUCCESS: {}", y);
    },
    Err(y) => {
    eprintln!("ERROR: {}", y);
    }
    }

    My solution has a following outline:

    -
    fn execute(&self, i: &Instruction, output: &mut Output) -> State {
    // execute the instruction

    // collect results if necessary
    match output {
    Output::Part1(x) => self.execute_part_1(y, x),
    Output::Part2(x) => self.execute_part_2(y, x),
    }

    // return the obtained state
    new_state
    }
    +
    fn execute(&self, i: &Instruction, output: &mut Output) -> State {
    // execute the instruction

    // collect results if necessary
    match output {
    Output::Part1(x) => self.execute_part_1(y, x),
    Output::Part2(x) => self.execute_part_2(y, x),
    }

    // return the obtained state
    new_state
    }

    You might think that it's a perfectly reasonable thing to do. Yes, but notice that the match statement doesn't collect the changes in any way and also we pass output by &mut, so it is shared across each iteration of the fold.

    @@ -251,7 +251,7 @@ also rolling down the hill…

    As I have said in the tl;dr, we are looking for the shortest path, but the start and goal differ for the part 1 and 2. So I have decided to refactor my solution to a BFS algorithm that takes necessary parameters via functions:

    -
    fn bfs<F, G>(
    graph: &[Vec<char>], start: &Position, has_edge: F, is_target: G
    ) -> Option<usize>
    where
    F: Fn(&[Vec<char>], &Position, &Position) -> bool,
    G: Fn(&[Vec<char>], &Position) -> bool
    +
    fn bfs<F, G>(
    graph: &[Vec<char>], start: &Position, has_edge: F, is_target: G
    ) -> Option<usize>
    where
    F: Fn(&[Vec<char>], &Position, &Position) -> bool,
    G: Fn(&[Vec<char>], &Position) -> bool

    We pass the initial vertex from the caller and everything else is left to the BFS algorithm, based on the has_edge and is_target functions.

    This was easy! And that is not very usual in Rust once you want to pass around @@ -268,7 +268,7 @@ time complexity, because of the priority heap instead of the queue.

    You can implement a lot of traits if you want to. It is imperative to implement ordering on the packets. I had a typo, so I also proceeded to implement a Display trait for debugging purposes:

    -
    impl Display for Packet {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
    Packet::Integer(x) => write!(f, "{x}"),
    Packet::List(lst) => write!(f, "[{}]", lst.iter().map(|p| format!("{p}")).join(",")),
    }
    }
    }
    +
    impl Display for Packet {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
    Packet::Integer(x) => write!(f, "{x}"),
    Packet::List(lst) => write!(f, "[{}]", lst.iter().map(|p| format!("{p}")).join(",")),
    }
    }
    }

    Solution

    A lot of technical details… Parsing is nasty too…

    Day 14: Regolith Reservoir

    @@ -288,16 +288,16 @@ leave it be, so I tried to implement the Index and IndexMutunsafe part are the 2 methods that are named *unchecked*. Anyways, I will be implementing the Index* traits for now, rather than the SliceIndex.

    It's relatively straightforward…

    -
    impl<I, C> Index<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    +
    impl<I, C> Index<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }

    We can see a lot of similarities to the implementation of index and index_mut functions. In the end, they are 1:1, just wrapped in the trait that provides a syntax sugar for container[idx].

    note

    I have also switched from using the TryFrom to TryInto trait, since it better matches what we are using, the .try_into rather than usize::try_from.

    Also implementing TryFrom automatically provides you with a TryInto trait, -since it is relatively easy to implement. Just compare the following:

    pub trait TryFrom<T>: Sized {
    type Error;

    fn try_from(value: T) -> Result<Self, Self::Error>;
    }

    pub trait TryInto<T>: Sized {
    type Error;

    fn try_into(self) -> Result<T, Self::Error>;
    }
    +since it is relatively easy to implement. Just compare the following:

    pub trait TryFrom<T>: Sized {
    type Error;

    fn try_from(value: T) -> Result<Self, Self::Error>;
    }

    pub trait TryInto<T>: Sized {
    type Error;

    fn try_into(self) -> Result<T, Self::Error>;
    }

    OK, so we have our trait implemented, we should be able to use container[index], right? Yes… but actually no 😦

    -
    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:26:18
    |
    26 | if trees[pos] > tallest {
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:30:28
    |
    30 | max(tallest, trees[pos])
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<isize>`
    --> src/bin/day08.rs:52:28
    |
    52 | let max_height = trees[position];
    | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<isize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<isize>>`
    +
    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:26:18
    |
    26 | if trees[pos] > tallest {
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:30:28
    |
    30 | max(tallest, trees[pos])
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<isize>`
    --> src/bin/day08.rs:52:28
    |
    52 | let max_height = trees[position];
    | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<isize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<isize>>`

    Why? We have it implemented for the slices ([C]), why doesn't it work? Well, the fun part consists of the fact that in other place, where we were using it, we were passing the &[Vec<T>], but this is coming from a helper functions that @@ -307,9 +307,9 @@ those. Just for the slices. 🤯 What are we going to do about it?

    so let's implement a macro! The only difference across the implementations are the types of the outer containers. Implementation doesn't differ at all!

    Implementing the macro can be done in a following way:

    -
    macro_rules! generate_indices {
    ($container:ty) => {
    impl<I, C> Index<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    };
    }
    +
    macro_rules! generate_indices {
    ($container:ty) => {
    impl<I, C> Index<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    };
    }

    And now we can simply do

    -
    generate_indices!(VecDeque<C>);
    generate_indices!([C]);
    generate_indices!(Vec<C>);
    // generate_indices!([C; N], const N: usize);
    +
    generate_indices!(VecDeque<C>);
    generate_indices!([C]);
    generate_indices!(Vec<C>);
    // generate_indices!([C; N], const N: usize);

    The last type (I took the inspiration from the implementations of the Index and IndexMut traits) is a bit problematic, because of the const N: usize part, which I haven't managed to be able to parse. And that's how I got rid of the error.

    @@ -319,11 +319,11 @@ copy-paste, cause the cost of this “monstrosity” outweighs the benefits of n

    This issue is relatively funny. If you don't use any type aliases, just the raw types, you'll get suggested certain changes by the clippy. For example if you consider the following piece of code

    -
    fn get_sum(nums: &Vec<i32>) -> i32 {
    nums.iter().sum()
    }

    fn main() {
    let nums = vec![1, 2, 3];
    println!("Sum: {}", get_sum(&nums));
    }
    +
    fn get_sum(nums: &Vec<i32>) -> i32 {
    nums.iter().sum()
    }

    fn main() {
    let nums = vec![1, 2, 3];
    println!("Sum: {}", get_sum(&nums));
    }

    and you run clippy on it, you will get

    -
    Checking playground v0.0.1 (/playground)
    warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
    --> src/main.rs:1:18
    |
    1 | fn get_sum(nums: &Vec<i32>) -> i32 {
    | ^^^^^^^^^ help: change this to: `&[i32]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
    = note: `#[warn(clippy::ptr_arg)]` on by default

    warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.61s
    +
    Checking playground v0.0.1 (/playground)
    warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
    --> src/main.rs:1:18
    |
    1 | fn get_sum(nums: &Vec<i32>) -> i32 {
    | ^^^^^^^^^ help: change this to: `&[i32]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
    = note: `#[warn(clippy::ptr_arg)]` on by default

    warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.61s

    However, if you introduce a type alias, such as

    -
    type Numbers = Vec<i32>;
    +
    type Numbers = Vec<i32>;

    Then clippy won't say anything, cause there is literally nothing to suggest. However the outcome is not the same…

    diff --git a/blog/aoc-2022/3rd-week/index.html b/blog/aoc-2022/3rd-week/index.html index 80db746..87d8650 100644 --- a/blog/aoc-2022/3rd-week/index.html +++ b/blog/aoc-2022/3rd-week/index.html @@ -14,8 +14,8 @@ - - + +

    3rd week of Advent of Code '22 in Rust

    · 12 min read
    Matej Focko

    Let's go through the third week of Advent of Code in Rust.

    @@ -37,7 +37,7 @@ to implement the indexing in a graph, rather than explicitly access the underlying data structure.

    Here you can see a rather short snippet from the solution that allows you to “index” the graph:

    -
    impl Index<&str> for Graph {
    type Output = Vertex;

    fn index(&self, index: &str) -> &Self::Output {
    &self.g[index]
    }
    }
    +
    impl Index<&str> for Graph {
    type Output = Vertex;

    fn index(&self, index: &str) -> &Self::Output {
    &self.g[index]
    }
    }

    Cartesian product

    During the implementation I had to utilize Floyd-Warshall algorithm for finding the shortest path between pairs of vertices and utilized the iproduct! macro @@ -51,7 +51,7 @@ also makes it harder to evaluate algorithmically, since you need to check the different ways the work can be split.

    Being affected by functional programming brain damage™️, I have chosen to do this part by function that returns an iterator over the possible ways:

    -
    fn pairings(
    valves: &BTreeSet<String>,
    ) -> impl Iterator<Item = (BTreeSet<String>, BTreeSet<String>)> + '_ {
    let mapping = valves.iter().collect_vec();

    let max_mask = 1 << (valves.len() - 1);

    (0..max_mask).map(move |mask| {
    let mut elephant = BTreeSet::new();
    let mut human = BTreeSet::new();

    for (i, &v) in mapping.iter().enumerate() {
    if (mask & (1 << i)) == 0 {
    human.insert(v.clone());
    } else {
    elephant.insert(v.clone());
    }
    }

    (human, elephant)
    })
    }
    +
    fn pairings(
    valves: &BTreeSet<String>,
    ) -> impl Iterator<Item = (BTreeSet<String>, BTreeSet<String>)> + '_ {
    let mapping = valves.iter().collect_vec();

    let max_mask = 1 << (valves.len() - 1);

    (0..max_mask).map(move |mask| {
    let mut elephant = BTreeSet::new();
    let mut human = BTreeSet::new();

    for (i, &v) in mapping.iter().enumerate() {
    if (mask & (1 << i)) == 0 {
    human.insert(v.clone());
    } else {
    elephant.insert(v.clone());
    }
    }

    (human, elephant)
    })
    }

    Day 17: Pyroclastic Flow

    tl;dr

    Simulating an autonomous Tetris where pieces get affected by a series of jets of hot gas.

    @@ -62,7 +62,7 @@ hot gas.

    iterate through the positions that can actually collide with the wall or other piece.

    To get the desired behaviour, you can just compose few smaller functions:

    -
    fn occupied(shape: &[Vec<char>]) -> impl Iterator<Item = Position> + '_ {
    shape.iter().enumerate().flat_map(|(y, row)| {
    row.iter().enumerate().filter_map(move |(x, c)| {
    if c == &'#' {
    Some(Vector2D::new(x as isize, y as isize))
    } else {
    None
    }
    })
    })
    }
    +
    fn occupied(shape: &[Vec<char>]) -> impl Iterator<Item = Position> + '_ {
    shape.iter().enumerate().flat_map(|(y, row)| {
    row.iter().enumerate().filter_map(move |(x, c)| {
    if c == &'#' {
    Some(Vector2D::new(x as isize, y as isize))
    } else {
    None
    }
    })
    })
    }

    In the end, we get relative positions which we can adjust later when given the specific positions from iterator. You can see some interesting parts in this:

      @@ -81,7 +81,7 @@ and also unwraps the values from Some(…). jets that move our pieces around. Initially I have implemented my own infinite iterator that just yields the indices. It is a very simple, yet powerful, piece of code:

      -
      struct InfiniteIndex {
      size: usize,
      i: usize,
      }

      impl InfiniteIndex {
      fn new(size: usize) -> InfiniteIndex {
      InfiniteIndex { size, i: size - 1 }
      }
      }

      impl Iterator for InfiniteIndex {
      type Item = usize;

      fn next(&mut self) -> Option<Self::Item> {
      self.i = (self.i + 1) % self.size;
      Some(self.i)
      }
      }
      +
      struct InfiniteIndex {
      size: usize,
      i: usize,
      }

      impl InfiniteIndex {
      fn new(size: usize) -> InfiniteIndex {
      InfiniteIndex { size, i: size - 1 }
      }
      }

      impl Iterator for InfiniteIndex {
      type Item = usize;

      fn next(&mut self) -> Option<Self::Item> {
      self.i = (self.i + 1) % self.size;
      Some(self.i)
      }
      }

      However when I'm looking at the code now, it doesn't really make much sense… Guess what, we can use a built-in function that is implemented on iterators for that! The function is called .cycle()

      @@ -127,13 +127,13 @@ the Rc<RefCell<T>>. In the end I failed on wrong an a rather interesting issue with .borrow_mut() method being used on Rc<RefCell<T>>.

      .borrow_mut()

      Consider the following snippet of the code (taken from the documentation):

      -
      use std::cell::{RefCell, RefMut};
      use std::collections::HashMap;
      use std::rc::Rc;
      // use std::borrow::BorrowMut;

      fn main() {
      let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
      // Create a new block to limit the scope of the dynamic borrow
      {
      let mut map: RefMut<_> = shared_map.borrow_mut();
      map.insert("africa", 92388);
      map.insert("kyoto", 11837);
      map.insert("piccadilly", 11826);
      map.insert("marbles", 38);
      }

      // Note that if we had not let the previous borrow of the cache fall out
      // of scope then the subsequent borrow would cause a dynamic thread panic.
      // This is the major hazard of using `RefCell`.
      let total: i32 = shared_map.borrow().values().sum();
      println!("{total}");
      }
      +
      use std::cell::{RefCell, RefMut};
      use std::collections::HashMap;
      use std::rc::Rc;
      // use std::borrow::BorrowMut;

      fn main() {
      let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
      // Create a new block to limit the scope of the dynamic borrow
      {
      let mut map: RefMut<_> = shared_map.borrow_mut();
      map.insert("africa", 92388);
      map.insert("kyoto", 11837);
      map.insert("piccadilly", 11826);
      map.insert("marbles", 38);
      }

      // Note that if we had not let the previous borrow of the cache fall out
      // of scope then the subsequent borrow would cause a dynamic thread panic.
      // This is the major hazard of using `RefCell`.
      let total: i32 = shared_map.borrow().values().sum();
      println!("{total}");
      }

      We allocate a hash map on the heap and then in the inner block, we borrow it as a mutable reference, so that we can use it.

      note

      It is a very primitive example for Rc<RefCell<T>> and mutable borrow.

      If you uncomment the 4th line with use std::borrow::BorrowMut;, you cannot compile the code anymore, because of

      -
         Compiling playground v0.0.1 (/playground)
      error[E0308]: mismatched types
      --> src/main.rs:10:34
      |
      10 | let mut map: RefMut<_> = shared_map.borrow_mut();
      | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference
      | |
      | expected due to this
      |
      = note: expected struct `RefMut<'_, _>`
      found mutable reference `&mut Rc<RefCell<HashMap<_, _>>>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:11:13
      |
      11 | map.insert("africa", 92388);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:12:13
      |
      12 | map.insert("kyoto", 11837);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:13:13
      |
      13 | map.insert("piccadilly", 11826);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:14:13
      |
      14 | map.insert("marbles", 38);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      Some errors have detailed explanations: E0308, E0599.
      For more information about an error, try `rustc --explain E0308`.
      error: could not compile `playground` due to 5 previous errors
      +
         Compiling playground v0.0.1 (/playground)
      error[E0308]: mismatched types
      --> src/main.rs:10:34
      |
      10 | let mut map: RefMut<_> = shared_map.borrow_mut();
      | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference
      | |
      | expected due to this
      |
      = note: expected struct `RefMut<'_, _>`
      found mutable reference `&mut Rc<RefCell<HashMap<_, _>>>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:11:13
      |
      11 | map.insert("africa", 92388);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:12:13
      |
      12 | map.insert("kyoto", 11837);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:13:13
      |
      13 | map.insert("piccadilly", 11826);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:14:13
      |
      14 | map.insert("marbles", 38);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      Some errors have detailed explanations: E0308, E0599.
      For more information about an error, try `rustc --explain E0308`.
      error: could not compile `playground` due to 5 previous errors

      It might seem a bit ridiculous. However, I got to a point where the compiler suggested use std::borrow::BorrowMut; and it resulted in breaking parts of the code that worked previously. I think it may be a good idea to go over what is @@ -160,14 +160,14 @@ method. OK, but how can we call it on the Rc<T>? Easily! I have not been able to find a lot on this trait. My guess is that it provides a method instead of a syntactic sugar (&mut x) for the mutable borrow. And also it provides default implementations for the types:

      -
      impl BorrowMut<str> for String

      impl<T> BorrowMut<T> for &mut T
      where
      T: ?Sized,

      impl<T> BorrowMut<T> for T
      where
      T: ?Sized,

      impl<T, A> BorrowMut<[T]> for Vec<T, A>
      where
      A: Allocator,

      impl<T, A> BorrowMut<T> for Box<T, A>
      where
      A: Allocator,
      T: ?Sized,

      impl<T, const N: usize> BorrowMut<[T]> for [T; N]
      +
      impl BorrowMut<str> for String

      impl<T> BorrowMut<T> for &mut T
      where
      T: ?Sized,

      impl<T> BorrowMut<T> for T
      where
      T: ?Sized,

      impl<T, A> BorrowMut<[T]> for Vec<T, A>
      where
      A: Allocator,

      impl<T, A> BorrowMut<T> for Box<T, A>
      where
      A: Allocator,
      T: ?Sized,

      impl<T, const N: usize> BorrowMut<[T]> for [T; N]
      Conflict

      Now the question is why did it break the code… My first take was that the type Rc<RefCell<T>> has some specialized implementation of the .borrow_mut() and the use overrides it with the default, which is true in a sense. However there is no specialized implementation. Let's have a look at the trait and the type signature on the RefCell<T>:

      -
      // trait
      pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
      where
      Borrowed: ?Sized,
      {
      fn borrow_mut(&mut self) -> &mut Borrowed;
      }

      // ‹RefCell<T>.borrow_mut()› type signature
      pub fn borrow_mut(&self) -> RefMut<'_, T>
      +
      // trait
      pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
      where
      Borrowed: ?Sized,
      {
      fn borrow_mut(&mut self) -> &mut Borrowed;
      }

      // ‹RefCell<T>.borrow_mut()› type signature
      pub fn borrow_mut(&self) -> RefMut<'_, T>

      I think that we can definitely agree on the fact that RefMut<'_, T> is not the RefCell<T>.

      In my opinion, RefCell<T> implements a separate .borrow_mut() rather @@ -194,7 +194,7 @@ as:

      that you can use the macro machinery to save yourself some typing. If you have enumeration of which the default value doesn't bear any parameter, you can just do2:

      -
      #[derive(Default)]
      enum Color {
      #[default]
      White,
      Gray,
      Black,
      }
      +
      #[derive(Default)]
      enum Color {
      #[default]
      White,
      Gray,
      Black,
      }

      Abusing negation

      If you want to use a unary minus operator on your own type, you can implement a Neg trait3. I was dealing with a binary tree and needed a way how to look diff --git a/blog/aoc-2022/4th-week/index.html b/blog/aoc-2022/4th-week/index.html index 18a5a63..87a7410 100644 --- a/blog/aoc-2022/4th-week/index.html +++ b/blog/aoc-2022/4th-week/index.html @@ -14,8 +14,8 @@ - - + +

      4th week of Advent of Code '22 in Rust

      · 16 min read
      Matej Focko

      Let's go through the fourth week of Advent of Code in Rust.

      @@ -35,17 +35,17 @@ each row and column to determine the boundaries, it was very easy to do for the rows (cause each row is a Vec element), but not for the columns, since they span multiple rows.

      For this use case I have implemented my own column iterator:

      -
      pub struct ColumnIterator<'a, T> {
      map: &'a [Vec<T>],
      column: usize,

      i: usize,
      }

      impl<'a, T> ColumnIterator<'a, T> {
      pub fn new(map: &'a [Vec<T>], column: usize) -> ColumnIterator<'a, T> {
      Self { map, column, i: 0 }
      }
      }

      impl<'a, T> Iterator for ColumnIterator<'a, T> {
      type Item = &'a T;

      fn next(&mut self) -> Option<Self::Item> {
      if self.i >= self.map.len() {
      return None;
      }

      self.i += 1;
      Some(&self.map[self.i - 1][self.column])
      }
      }
      +
      pub struct ColumnIterator<'a, T> {
      map: &'a [Vec<T>],
      column: usize,

      i: usize,
      }

      impl<'a, T> ColumnIterator<'a, T> {
      pub fn new(map: &'a [Vec<T>], column: usize) -> ColumnIterator<'a, T> {
      Self { map, column, i: 0 }
      }
      }

      impl<'a, T> Iterator for ColumnIterator<'a, T> {
      type Item = &'a T;

      fn next(&mut self) -> Option<Self::Item> {
      if self.i >= self.map.len() {
      return None;
      }

      self.i += 1;
      Some(&self.map[self.i - 1][self.column])
      }
      }

      Given this piece of an iterator, it is very easy to factor out the common functionality between the rows and columns into:

      -
      let mut find_boundaries = |constructor: fn(usize) -> Orientation,
      iterator: &mut dyn Iterator<Item = &char>,
      upper_bound,
      i| {
      let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == ' ');
      let start = first_non_empty.next().unwrap().0 as isize;

      let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
      let end = last_non_empty.next().unwrap_or((upper_bound, &'_')).0 as isize;

      boundaries.insert(constructor(i), start..end);
      };
      +
      let mut find_boundaries = |constructor: fn(usize) -> Orientation,
      iterator: &mut dyn Iterator<Item = &char>,
      upper_bound,
      i| {
      let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == ' ');
      let start = first_non_empty.next().unwrap().0 as isize;

      let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
      let end = last_non_empty.next().unwrap_or((upper_bound, &'_')).0 as isize;

      boundaries.insert(constructor(i), start..end);
      };

      And then use it as such:

      -
      // construct all horizontal boundaries
      (0..map.len()).for_each(|row| {
      find_boundaries(
      Orientation::horizontal,
      &mut map[row].iter(),
      map[row].len(),
      row,
      );
      });

      // construct all vertical boundaries
      (0..map[0].len()).for_each(|col| {
      find_boundaries(
      Orientation::vertical,
      &mut ColumnIterator::new(&map, col),
      map.len(),
      col,
      );
      });
      +
      // construct all horizontal boundaries
      (0..map.len()).for_each(|row| {
      find_boundaries(
      Orientation::horizontal,
      &mut map[row].iter(),
      map[row].len(),
      row,
      );
      });

      // construct all vertical boundaries
      (0..map[0].len()).for_each(|col| {
      find_boundaries(
      Orientation::vertical,
      &mut ColumnIterator::new(&map, col),
      map.len(),
      col,
      );
      });

      Walking around the map

      Once the 2nd part got introduced, you start to think about a way how not to copy-paste a lot of stuff (I haven't avoided it anyways…). In this problem, I've chosen to introduce a trait (i.e. interface) for 2D and 3D walker.

      -
      trait Wrap: Clone {
      type State;

      // simulation
      fn is_blocked(&self) -> bool;
      fn step(&mut self, steps: isize);
      fn turn_left(&mut self);
      fn turn_right(&mut self);

      // movement
      fn next(&self) -> (Self::State, Direction);

      // final answer
      fn answer(&self) -> Output;
      }
      +
      trait Wrap: Clone {
      type State;

      // simulation
      fn is_blocked(&self) -> bool;
      fn step(&mut self, steps: isize);
      fn turn_left(&mut self);
      fn turn_right(&mut self);

      // movement
      fn next(&self) -> (Self::State, Direction);

      // final answer
      fn answer(&self) -> Output;
      }

      Each walker maintains its own state and also provides the functions that are used during the simulation. The “promised” methods are separated into:

        @@ -57,7 +57,7 @@ implementation-specific walker

      Both 2D and 3D versions borrow the original input and therefore you must annotate the lifetime of it:

      -
      struct Wrap2D<'a> {
      input: &'a Input,
      position: Position,
      direction: Direction,
      }
      impl<'a> Wrap2D<'a> {
      fn new(input: &'a Input) -> Wrap2D<'a> {
      // …
      +
      struct Wrap2D<'a> {
      input: &'a Input,
      position: Position,
      direction: Direction,
      }
      impl<'a> Wrap2D<'a> {
      fn new(input: &'a Input) -> Wrap2D<'a> {
      // …

      Problems

      I have used a lot of closures for this problem and once I introduced a parameter that was of unknown type (apart from the fact it implements a specific trait), I @@ -74,13 +74,13 @@ of rather smart suggestions.

      char was the .is_digit() function that takes a radix as a parameter. Clippy noticed that I use radix = 10 and suggested switching to .is_ascii_digit() that does exactly the same thing:

      -
      -                .take_while(|c| c.is_digit(10))
      + .take_while(|c| c.is_ascii_digit())
      +
      -                .take_while(|c| c.is_digit(10))
      + .take_while(|c| c.is_ascii_digit())

      Another useful suggestion appeared when working with the iterators and I wanted to get the nn-th element from it. You know the .skip(), you know the .next(), just “slap” them together and we're done for 😁 Well, I got suggested to use .nth() that does exactly the combination of the two mentioned methods on iterators:

      -
      -            match it.clone().skip(skip).next().unwrap() {
      + match it.clone().nth(skip).unwrap() {
      +
      -            match it.clone().skip(skip).next().unwrap() {
      + match it.clone().nth(skip).unwrap() {

      Day 23: Unstable Diffusion

      tl;dr

      Simulating movement of elves around with a set of specific rules.

      Solution

      @@ -93,20 +93,20 @@ minimum that are, of course, exactly the same except for initial values and comparators, it looks like a rather simple fix, but typing in Rust is something else, right? In the end I settled for a function that computes both boundaries without any duplication while using a closure:

      -
      fn get_bounds(positions: &Input) -> (Vector2D<isize>, Vector2D<isize>) {
      let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {
      positions
      .iter()
      .fold(Vector2D::new(init, init), |acc, elf| {
      Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))
      })
      };

      (f(isize::MAX, &min::<isize>), f(isize::MIN, &max::<isize>))
      }
      +
      fn get_bounds(positions: &Input) -> (Vector2D<isize>, Vector2D<isize>) {
      let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {
      positions
      .iter()
      .fold(Vector2D::new(init, init), |acc, elf| {
      Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))
      })
      };

      (f(isize::MAX, &min::<isize>), f(isize::MIN, &max::<isize>))
      }

      This function returns a pair of 2D vectors that represent opposite points of the bounding rectangle of all elves.

      You might ask why would we need a closure and the answer is that positions cannot be captured from within the nested function, only via closure. One more fun fact on top of that is the type of the comparator

      -
      &dyn Fn(isize, isize) -> isize
      +
      &dyn Fn(isize, isize) -> isize

      Once we remove the dyn keyword, compiler yells at us and also includes a way how to get a more thorough explanation of the error by running

      $ rustc --explain E0782

      which shows us

      Trait objects must include the dyn keyword.

      Erroneous code example:

      -
      trait Foo {}
      fn test(arg: Box<Foo>) {} // error!
      +
      trait Foo {}
      fn test(arg: Box<Foo>) {} // error!

      Trait objects are a way to call methods on types that are not known until runtime but conform to some trait.

      Trait objects should be formed with Box<dyn Foo>, but in the code above @@ -114,7 +114,7 @@ runtime but conform to some trait.

      This makes it harder to see that arg is a trait object and not a simply a heap allocated type called Foo.

      To fix this issue, add dyn before the trait name.

      -
      trait Foo {}
      fn test(arg: Box<dyn Foo>) {} // ok!
      +
      trait Foo {}
      fn test(arg: Box<dyn Foo>) {} // ok!

      This used to be allowed before edition 2021, but is now an error.

      Rant

      Not all of the explanations are helpful though, in some cases they might be even more confusing than helpful, since they address very simple use cases.

      As you can see, even in this case there are two sides to the explanations:

        @@ -157,7 +157,7 @@ cleaned it up a bit. The changed version is shown here and the original was just more verbose.

      I'll skip the boring parts of checking bounds and entry/exit of the basin 😉 We can easily calculate positions of the blizzards using a modular arithmetics:

      -
      impl Index<Position> for Basin {
      type Output = char;

      fn index(&self, index: Position) -> &Self::Output {
      // ‹skipped boring parts›

      // We need to account for the loops of the blizzards
      let width = self.cols - 2;
      let height = self.rows - 2;

      let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;
      [
      (
      index.y() as usize,
      blizzard_origin(width, -1, index.z(), index.x()),
      '>',
      ),
      (
      index.y() as usize,
      blizzard_origin(width, 1, index.z(), index.x()),
      '<',
      ),
      (
      blizzard_origin(height, -1, index.z(), index.y()),
      index.x() as usize,
      'v',
      ),
      (
      blizzard_origin(height, 1, index.z(), index.y()),
      index.x() as usize,
      '^',
      ),
      ]
      .iter()
      .find_map(|&(y, x, direction)| {
      if self.map[y][x] == direction {
      Some(&self.map[y][x])
      } else {
      None
      }
      })
      .unwrap_or(&'.')
      }
      }
      +
      impl Index<Position> for Basin {
      type Output = char;

      fn index(&self, index: Position) -> &Self::Output {
      // ‹skipped boring parts›

      // We need to account for the loops of the blizzards
      let width = self.cols - 2;
      let height = self.rows - 2;

      let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;
      [
      (
      index.y() as usize,
      blizzard_origin(width, -1, index.z(), index.x()),
      '>',
      ),
      (
      index.y() as usize,
      blizzard_origin(width, 1, index.z(), index.x()),
      '<',
      ),
      (
      blizzard_origin(height, -1, index.z(), index.y()),
      index.x() as usize,
      'v',
      ),
      (
      blizzard_origin(height, 1, index.z(), index.y()),
      index.x() as usize,
      '^',
      ),
      ]
      .iter()
      .find_map(|&(y, x, direction)| {
      if self.map[y][x] == direction {
      Some(&self.map[y][x])
      } else {
      None
      }
      })
      .unwrap_or(&'.')
      }
      }

      As you can see, there is an expression for calculating the original position and it's used multiple times, so why not take it out to a lambda, right? 😉

      I couldn't get the rustfmt to format the for-loop nicely, so I've just @@ -175,10 +175,10 @@ algorithm, since it better reflects the cost function.

      a priority for the queue.

      Whereas with the A*, I have chosen to use both time and Manhattan distance that promotes vertices closer to the exit and with a minimum time taken.

      Cost function is, of course, a closure 😉

      -
      let cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());
      +
      let cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());

      And also for checking the possible moves from the current vertex, I have implemented, yet another, closure that yields an iterator with the next moves:

      -
      let next_positions = |p| {
      [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]
      .iter()
      .filter_map(move |&(x, y, t)| {
      let next_p = p + Vector3D::new(x, y, t);

      if basin[next_p] == '.' {
      Some(next_p)
      } else {
      None
      }
      })
      };
      +
      let next_positions = |p| {
      [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]
      .iter()
      .filter_map(move |&(x, y, t)| {
      let next_p = p + Vector3D::new(x, y, t);

      if basin[next_p] == '.' {
      Some(next_p)
      } else {
      None
      }
      })
      };

      Min-heap

      In this case I had a need to use the priority queue taking the elements with the lowest cost as the prioritized ones. Rust only offers you the BinaryHeap and @@ -188,7 +188,7 @@ the BinaryHeap). However the wrapping affects the type of the h popping the most prioritized elements yields values wrapped in the Reverse.

      For this purpose I have just taken the max-heap and wrapped it as a whole in a separate structure providing just the desired methods:

      -
      use std::cmp::{Ord, Reverse};
      use std::collections::BinaryHeap;

      pub struct MinHeap<T> {
      heap: BinaryHeap<Reverse<T>>,
      }

      impl<T: Ord> MinHeap<T> {
      pub fn new() -> MinHeap<T> {
      MinHeap {
      heap: BinaryHeap::new(),
      }
      }

      pub fn push(&mut self, item: T) {
      self.heap.push(Reverse(item))
      }

      pub fn pop(&mut self) -> Option<T> {
      self.heap.pop().map(|Reverse(x)| x)
      }
      }

      impl<T: Ord> Default for MinHeap<T> {
      fn default() -> Self {
      Self::new()
      }
      }
      +
      use std::cmp::{Ord, Reverse};
      use std::collections::BinaryHeap;

      pub struct MinHeap<T> {
      heap: BinaryHeap<Reverse<T>>,
      }

      impl<T: Ord> MinHeap<T> {
      pub fn new() -> MinHeap<T> {
      MinHeap {
      heap: BinaryHeap::new(),
      }
      }

      pub fn push(&mut self, item: T) {
      self.heap.push(Reverse(item))
      }

      pub fn pop(&mut self) -> Option<T> {
      self.heap.pop().map(|Reverse(x)| x)
      }
      }

      impl<T: Ord> Default for MinHeap<T> {
      fn default() -> Self {
      Self::new()
      }
      }

      Rest is just the algorithm implementation which is not that interesting.

      Day 25: Full of Hot Air

      tl;dr

      Playing around with a numbers in a special base.

      @@ -205,7 +205,7 @@ with a rather easy solution, as the last day always seems to be.

      that sounds familiar, doesn't it? Let's introduce a structure for the SNAFU numbers and implement the traits that we need.

      Let's start with a structure:

      -
      #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
      struct SNAFU {
      value: i64,
      }
      +
      #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
      struct SNAFU {
      value: i64,
      }

      Converting from &str

      We will start by implementing the FromStr trait that will help us parse our input. This is rather simple, I can just take the from_snafu function, copy-paste it @@ -224,13 +224,13 @@ trait for the SNAFU.

      After those changes we need to adjust the code and tests.

      Parsing of the input is very easy, before we have used the lines, now we parse everything:

      -
           fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
      - file_to_lines(pathname)
      + file_to_structs(pathname)
      }
      +
           fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
      - file_to_lines(pathname)
      + file_to_structs(pathname)
      }

      Part 1 needs to be adjusted a bit too:

      -
           fn part_1(input: &Input) -> Output {
      - to_snafu(input.iter().map(|s| from_snafu(s)).sum())
      + SNAFU::from(input.iter().map(|s| s.value).sum::<i64>()).to_string()
      }
      +
           fn part_1(input: &Input) -> Output {
      - to_snafu(input.iter().map(|s| from_snafu(s)).sum())
      + SNAFU::from(input.iter().map(|s| s.value).sum::<i64>()).to_string()
      }

      You can also see that it simplifies the meaning a bit and it is more explicit than the previous versions.

      And for the tests:

      -
           #[test]
      fn test_from() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(from_snafu(s), *n);
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(s.parse::<SNAFU>().unwrap().value, n);
      }
      }

      #[test]
      fn test_to() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(to_snafu(*n), s.to_string());
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(SNAFU::from(n).to_string(), s.to_string());
      }
      +
           #[test]
      fn test_from() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(from_snafu(s), *n);
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(s.parse::<SNAFU>().unwrap().value, n);
      }
      }

      #[test]
      fn test_to() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(to_snafu(*n), s.to_string());
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(SNAFU::from(n).to_string(), s.to_string());
      }

      Summary

      Let's wrap the whole thing up! Keeping in mind both AoC and the Rust…

      Finished advent calendar :smile:

      diff --git a/blog/aoc-2022/intro/index.html b/blog/aoc-2022/intro/index.html index 2db0cda..102adfe 100644 --- a/blog/aoc-2022/intro/index.html +++ b/blog/aoc-2022/intro/index.html @@ -14,8 +14,8 @@ - - + +

      Advent of Code '22 in Rust

      · 9 min read
      Matej Focko

      Let's talk about the preparations for this year's Advent of Code.

      @@ -50,15 +50,15 @@ problems in it. However the toolkit is questionable :/

      with rust-analyzer. Because of my choice of libraries, we will also introduce a .envrc file that can be used by direnv, which allows you to set specific environment variables when you enter a directory. In our case, we will use

      -
      # to show nice backtrace when using the color-eyre
      export RUST_BACKTRACE=1

      # to catch logs generated by tracing
      export RUST_LOG=trace
      +
      # to show nice backtrace when using the color-eyre
      export RUST_BACKTRACE=1

      # to catch logs generated by tracing
      export RUST_LOG=trace

      And for the one of the most obnoxious things ever, we will use a script to download the inputs instead of “clicking, opening and copying to a file1. There is no need to be fancy, so we will adjust Python script by Martin2.

      -
      #!/usr/bin/env python3

      import datetime
      import yaml
      import requests
      import sys


      def load_config():
      with open("env.yaml", "r") as f:
      js = yaml.load(f, Loader=yaml.Loader)
      return js["session"], js["year"]


      def get_input(session, year, day):
      return requests.get(
      f"https://adventofcode.com/{year}/day/{day}/input",
      cookies={"session": session},
      headers={
      "User-Agent": "{repo} by {mail}".format(
      repo="gitlab.com/mfocko/advent-of-code-2022",
      mail="me@mfocko.xyz",
      )
      },
      ).content.decode("utf-8")


      def main():
      day = datetime.datetime.now().day
      if len(sys.argv) == 2:
      day = sys.argv[1]

      session, year = load_config()
      problem_input = get_input(session, year, day)

      with open(f"./inputs/day{day:>02}.txt", "w") as f:
      f.write(problem_input)


      if __name__ == "__main__":
      main()
      +
      #!/usr/bin/env python3

      import datetime
      import yaml
      import requests
      import sys


      def load_config():
      with open("env.yaml", "r") as f:
      js = yaml.load(f, Loader=yaml.Loader)
      return js["session"], js["year"]


      def get_input(session, year, day):
      return requests.get(
      f"https://adventofcode.com/{year}/day/{day}/input",
      cookies={"session": session},
      headers={
      "User-Agent": "{repo} by {mail}".format(
      repo="gitlab.com/mfocko/advent-of-code-2022",
      mail="me@mfocko.xyz",
      )
      },
      ).content.decode("utf-8")


      def main():
      day = datetime.datetime.now().day
      if len(sys.argv) == 2:
      day = sys.argv[1]

      session, year = load_config()
      problem_input = get_input(session, year, day)

      with open(f"./inputs/day{day:>02}.txt", "w") as f:
      f.write(problem_input)


      if __name__ == "__main__":
      main()

      If the script is called without any arguments, it will deduce the day from the system, so we do not need to change the day every morning. It also requires a configuration file:

      -
      # env.yaml
      session: ‹your session cookie›
      year: 2022
      +
      # env.yaml
      session: ‹your session cookie›
      year: 2022

      Libraries

      Looking at the list of the libraries, I have chosen “a lot” of them. Let's walk through each of them.

      @@ -87,7 +87,7 @@ also we can follow KISS. I have 2 modules that my “library” exports parsing and one for 2D vector (that gets used quite often during Advent of Code).

      Key part is, of course, processing the input and my library exports following functions that get used a lot:

      -
      /// Reads file to the string.
      pub fn file_to_string<P: AsRef<Path>>(pathname: P) -> String;

      /// Reads file and returns it as a vector of characters.
      pub fn file_to_chars<P: AsRef<Path>>(pathname: P) -> Vec<char>;

      /// Reads file and returns a vector of parsed structures. Expects each structure
      /// on its own line in the file. And `T` needs to implement `FromStr` trait.
      pub fn file_to_structs<P: AsRef<Path>, T: FromStr>(pathname: P) -> Vec<T>
      where
      <T as FromStr>::Err: Debug;

      /// Converts iterator over strings to a vector of parsed structures. `T` needs
      /// to implement `FromStr` trait and its error must derive `Debug` trait.
      pub fn strings_to_structs<T: FromStr, U>(
      iter: impl Iterator<Item = U>
      ) -> Vec<T>
      where
      <T as std::str::FromStr>::Err: std::fmt::Debug,
      U: Deref<Target = str>;

      /// Reads file and returns it as a vector of its lines.
      pub fn file_to_lines<P: AsRef<Path>>(pathname: P) -> Vec<String>;
      +
      /// Reads file to the string.
      pub fn file_to_string<P: AsRef<Path>>(pathname: P) -> String;

      /// Reads file and returns it as a vector of characters.
      pub fn file_to_chars<P: AsRef<Path>>(pathname: P) -> Vec<char>;

      /// Reads file and returns a vector of parsed structures. Expects each structure
      /// on its own line in the file. And `T` needs to implement `FromStr` trait.
      pub fn file_to_structs<P: AsRef<Path>, T: FromStr>(pathname: P) -> Vec<T>
      where
      <T as FromStr>::Err: Debug;

      /// Converts iterator over strings to a vector of parsed structures. `T` needs
      /// to implement `FromStr` trait and its error must derive `Debug` trait.
      pub fn strings_to_structs<T: FromStr, U>(
      iter: impl Iterator<Item = U>
      ) -> Vec<T>
      where
      <T as std::str::FromStr>::Err: std::fmt::Debug,
      U: Deref<Target = str>;

      /// Reads file and returns it as a vector of its lines.
      pub fn file_to_lines<P: AsRef<Path>>(pathname: P) -> Vec<String>;

      As for the vector, I went with a rather simple implementation that allows only addition of the vectors for now and accessing the elements via functions x() and y(). Also the vector is generic, so we can use it with any numeric type we @@ -96,36 +96,36 @@ need.

      We can also prepare a template to quickly bootstrap each of the days. We know that each puzzle has 2 parts, which means that we can start with 2 functions that will solve them.

      -
      fn part1(input: &Input) -> Output {
      todo!()
      }

      fn part2(input: &Input) -> Output {
      todo!()
      }
      +
      fn part1(input: &Input) -> Output {
      todo!()
      }

      fn part2(input: &Input) -> Output {
      todo!()
      }

      Both functions take reference to the input and return some output (in majority of puzzles, it is the same type). todo!() can be used as a nice placeholder, it also causes a panic when reached and we could also provide some string with an explanation, e.g. todo!("part 1"). We have not given functions a specific type and to avoid as much copy-paste as possible, we will introduce type aliases.

      -
      type Input = String;
      type Output = i32;
      +
      type Input = String;
      type Output = i32;
      tip

      This allows us to quickly adjust the types only in one place without the need to do regex-replace or replace them manually.

      For each day we get a personalized input that is provided as a text file. Almost all the time, we would like to get some structured type out of that input, and therefore it makes sense to introduce a new function that will provide the parsing of the input.

      -
      fn parse_input(path: &str) -> Input {
      todo!()
      }
      +
      fn parse_input(path: &str) -> Input {
      todo!()
      }

      This “parser” will take a path to the file, just in case we would like to run the sample instead of input.

      OK, so now we can write a main function that will take all of the pieces and run them.

      -
      fn main() {
      let input = parse_input("inputs/dayXX.txt");

      println!("Part 1: {}", part_1(&input));
      println!("Part 2: {}", part_2(&input));
      }
      +
      fn main() {
      let input = parse_input("inputs/dayXX.txt");

      println!("Part 1: {}", part_1(&input));
      println!("Part 2: {}", part_2(&input));
      }

      This would definitely do :) But we have installed a few libraries and we want to use them. In this part we are going to utilize tracing (for tracing, duh…) and color-eyre (for better error reporting, e.g. from parsing).

      -
      fn main() -> Result<()> {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = parse_input("inputs/dayXX.txt");

      info!("Part 1: {}", part_1(&input));
      info!("Part 2: {}", part_2(&input));

      Ok(())
      }
      +
      fn main() -> Result<()> {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = parse_input("inputs/dayXX.txt");

      info!("Part 1: {}", part_1(&input));
      info!("Part 2: {}", part_2(&input));

      Ok(())
      }

      The first statement will set up tracing and configure it to print out the logs to terminal, based on the environment variable. We also change the formatting a bit, since we do not need all the fancy features of the logger. Pure initialization would get us logs like this:

      -
      2022-12-11T19:53:19.975343Z  INFO day01: Part 1: 0
      +
      2022-12-11T19:53:19.975343Z  INFO day01: Part 1: 0

      However after running that command, we will get the following:

      -
       INFO src/bin/day01.rs:35: Part 1: 0
      +
       INFO src/bin/day01.rs:35: Part 1: 0

      And the color_eyre::install()? is quite straightforward. We just initialize the error reporting by color eyre.

      caution

      Notice that we had to add Ok(()) to the end of the function and adjust the @@ -133,7 +133,7 @@ return type of the main to Result<()>. It is cau can be installed only once and therefore it can fail, that is how we got the ? at the end of the ::install which unwraps the »result« of the installation.

      Overall we will get to a template like this:

      -
      use aoc_2022::*;

      use color_eyre::eyre::Result;
      use tracing::info;
      use tracing_subscriber::EnvFilter;

      type Input = String;
      type Output = i32;

      fn parse_input(path: &str) -> Input {
      todo!()
      }

      fn part1(input: &Input) -> Output {
      todo!()
      }

      fn part2(input: &Input) -> Output {
      todo!()
      }

      fn main() -> Result<()> {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = parse_input("inputs/dayXX.txt");

      info!("Part 1: {}", part_1(&input));
      info!("Part 2: {}", part_2(&input));

      Ok(())
      }
      +
      use aoc_2022::*;

      use color_eyre::eyre::Result;
      use tracing::info;
      use tracing_subscriber::EnvFilter;

      type Input = String;
      type Output = i32;

      fn parse_input(path: &str) -> Input {
      todo!()
      }

      fn part1(input: &Input) -> Output {
      todo!()
      }

      fn part2(input: &Input) -> Output {
      todo!()
      }

      fn main() -> Result<()> {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = parse_input("inputs/dayXX.txt");

      info!("Part 1: {}", part_1(&input));
      info!("Part 2: {}", part_2(&input));

      Ok(())
      }

      Footnotes

      1. diff --git a/blog/archive/index.html b/blog/archive/index.html index cbef0f0..c5d54aa 100644 --- a/blog/archive/index.html +++ b/blog/archive/index.html @@ -14,8 +14,8 @@ - - + + diff --git a/blog/atom.xml b/blog/atom.xml index b3cf128..9d119e0 100644 --- a/blog/atom.xml +++ b/blog/atom.xml @@ -78,7 +78,7 @@ will make people dull and they should think about it anyways, that's ho issue above has been discovered. If everyone walked past and didn't think about it, no one would discover this issue till it bit them hard.

        Standard library

        Even the standard library is littered with unsafe blocks that are prefixed -with comments in style:

        // SAFETY: …

        The fact that the casual Rust dev doesn't have to think much about safety, +with comments in style:

        // SAFETY: …

        The fact that the casual Rust dev doesn't have to think much about safety, cause the compiler has their back, doesn't mean that the Rust compiler dev doesn't either.

        I gotta admit that I adopted this concept in other languages (even in Python), cause you can encounter situations where it doesn't have to be clear why you @@ -100,7 +100,7 @@ as the Rust one.

        One of the other negatives is the introduction of bugs. If you're pushing changes, somewhat mindlessly, at such a fast pace, it is inevitable to introduce a bunch bugs in the process. Checking the GitHub issue tracker with

        -
        is:issue is:open label:C-bug label:T-compiler
        +
        is:issue is:open label:C-bug label:T-compiler

        yields 2,224 open issues at the time of writing this post.

        RFCs

        You can find a lot of RFCs for the Rust. Some of them are more questionable @@ -108,13 +108,13 @@ than the others. Fun thing is that a lot of them make it to the nightly builds, so they can be tested and polished off. Even the questionable ones… I'll leave few examples for a better understanding.

        One of such features is the do yeet expression:

        -
        #![feature(yeet_expr)]

        fn foo() -> Result<String, i32> {
        do yeet 4;
        }
        assert_eq!(foo(), Err(4));

        fn bar() -> Option<String> {
        do yeet;
        }
        assert_eq!(bar(), None);
        +
        #![feature(yeet_expr)]

        fn foo() -> Result<String, i32> {
        do yeet 4;
        }
        assert_eq!(foo(), Err(4));

        fn bar() -> Option<String> {
        do yeet;
        }
        assert_eq!(bar(), None);

        It allows you to “yeet” the errors out of the functions that return Result or Option.

        One of the more recent ones is the ability to include Cargo manifests into the sources, so you can do something like:

        -
        #!/usr/bin/env cargo
        ---
        [dependencies]
        clap = { version = "4.2", features = ["derive"] }
        ---

        use clap::Parser;

        #[derive(Parser, Debug)]
        #[clap(version)]
        struct Args {
        #[clap(short, long, help = "Path to config")]
        config: Option<std::path::PathBuf>,
        }

        fn main() {
        let args = Args::parse();
        println!("{:?}", args);
        }
        +
        #!/usr/bin/env cargo
        ---
        [dependencies]
        clap = { version = "4.2", features = ["derive"] }
        ---

        use clap::Parser;

        #[derive(Parser, Debug)]
        #[clap(version)]
        struct Args {
        #[clap(short, long, help = "Path to config")]
        config: Option<std::path::PathBuf>,
        }

        fn main() {
        let args = Args::parse();
        println!("{:?}", args);
        }

        I would say you can get almost anything into the language…

        Community and hype train

        Rust community is a rather unique thing. A lot of people will hate me for this, @@ -190,10 +190,10 @@ have to admit it's much easier to remember the bad stuff as opposed to the good.

        I prefered using Rust for the Advent of Code and Codeforces as it provides a rather easy way to test the solutions before running them with the challenge input (or test runner). I can give an example from the Advent of Code:

        -
        use aoc_2023::*;

        type Output1 = i32;
        type Output2 = Output1;

        struct DayXX {}
        impl Solution<Output1, Output2> for DayXX {
        fn new<P: AsRef<Path>>(pathname: P) -> Self {
        let lines: Vec<String> = file_to_lines(pathname);

        todo!()
        }

        fn part_1(&mut self) -> Output1 {
        todo!()
        }

        fn part_2(&mut self) -> Output2 {
        todo!()
        }
        }

        fn main() -> Result<()> {
        DayXX::main()
        }

        test_sample!(day_XX, DayXX, 42, 69);
        +
        use aoc_2023::*;

        type Output1 = i32;
        type Output2 = Output1;

        struct DayXX {}
        impl Solution<Output1, Output2> for DayXX {
        fn new<P: AsRef<Path>>(pathname: P) -> Self {
        let lines: Vec<String> = file_to_lines(pathname);

        todo!()
        }

        fn part_1(&mut self) -> Output1 {
        todo!()
        }

        fn part_2(&mut self) -> Output2 {
        todo!()
        }
        }

        fn main() -> Result<()> {
        DayXX::main()
        }

        test_sample!(day_XX, DayXX, 42, 69);

        This was the skeleton I've used and the macro at the end is my own creation that expands to:

        -
        #[cfg(test)]
        mod day_XX {
        use super::*;

        #[test]
        fn part_1() {
        let path = DayXX::get_sample(1);
        let mut day = DayXX::new(path);
        assert_eq!(day.part_1(), 42);
        }

        #[test]
        fn part_2() {
        let path = DayXX::get_sample(2);
        let mut day = DayXX::new(path);
        assert_eq!(day.part_2(), 69);
        }
        }
        +
        #[cfg(test)]
        mod day_XX {
        use super::*;

        #[test]
        fn part_1() {
        let path = DayXX::get_sample(1);
        let mut day = DayXX::new(path);
        assert_eq!(day.part_1(), 42);
        }

        #[test]
        fn part_2() {
        let path = DayXX::get_sample(2);
        let mut day = DayXX::new(path);
        assert_eq!(day.part_2(), 69);
        }
        }

        When you're solving the problem, all you need to do is switch between cargo test and cargo run to check the answer to either sample or the challenge input itself.

        @@ -218,7 +218,7 @@ language is a good habit, as I've mentioned above. You should be able to argue why you can do something safely, even if the compiler is not kicking your ass because of it.

        Excerpt of such comment from work:

        -
        # SAFETY: Taking first package instead of specific package should be
        # safe, since we have put a requirement on »one« ‹upstream_project_url›
        # per Packit config, i.e. even if we're dealing with a monorepo, there
        # is only »one« upstream. If there is one upstream, there is only one
        # set of GPG keys that can be allowed.
        return self.downstream_config.packages[
        self.downstream_config._first_package
        ].allowed_gpg_keys
        +
        # SAFETY: Taking first package instead of specific package should be
        # safe, since we have put a requirement on »one« ‹upstream_project_url›
        # per Packit config, i.e. even if we're dealing with a monorepo, there
        # is only »one« upstream. If there is one upstream, there is only one
        # set of GPG keys that can be allowed.
        return self.downstream_config.packages[
        self.downstream_config._first_package
        ].allowed_gpg_keys

        Traits

        One of the other things I like are the traits. They are more restrictive than templates or concepts in C++, but they're doing their job pretty good. If you @@ -227,12 +227,12 @@ of copy-paste, but that's soon to be fixed by the

      +order based on the complexity they can express:

      Rust's trait < Haskell's type class < C++'s concept

      You can also hit some issues, like me when trying to support conversions between underlying numeric types of a 2D vectors or support for using an operator from both sides (I couldn't get c * u to work in the same way as u * c because the first one requires you to implement the trait of a built-in type).

      -
      Implementation

      Implementing traits lies in

      impl SomeTrait for SomeStruct {
      // implementation goes here
      }

      One of the things I would love to see is being able to define the helper +

      Implementation

      Implementing traits lies in

      impl SomeTrait for SomeStruct {
      // implementation goes here
      }

      One of the things I would love to see is being able to define the helper functions within the same block. As of now, the only things allowed are the ones that are required by the trait, which in the end results in a randomly lying functions around (or in a implementation of the structure itself). I don't like @@ -316,7 +316,7 @@ very close to installing the desired package.

      So in shell you would do

      -
      # dnf copr enable ‹copr-repository›
      # dnf install ‹package-from-the-repository›
      +
      # dnf copr enable ‹copr-repository›
      # dnf install ‹package-from-the-repository›

      And… that's it! Nothing else needed! Simple, right? And literally same process as you would do for the PPA.

      AUR

      On the other hand, if you are familiar with the archLinux, you definitely know @@ -403,17 +403,17 @@ each row and column to determine the boundaries, it was very easy to do for the rows (cause each row is a Vec element), but not for the columns, since they span multiple rows.

      For this use case I have implemented my own column iterator:

      -
      pub struct ColumnIterator<'a, T> {
      map: &'a [Vec<T>],
      column: usize,

      i: usize,
      }

      impl<'a, T> ColumnIterator<'a, T> {
      pub fn new(map: &'a [Vec<T>], column: usize) -> ColumnIterator<'a, T> {
      Self { map, column, i: 0 }
      }
      }

      impl<'a, T> Iterator for ColumnIterator<'a, T> {
      type Item = &'a T;

      fn next(&mut self) -> Option<Self::Item> {
      if self.i >= self.map.len() {
      return None;
      }

      self.i += 1;
      Some(&self.map[self.i - 1][self.column])
      }
      }
      +
      pub struct ColumnIterator<'a, T> {
      map: &'a [Vec<T>],
      column: usize,

      i: usize,
      }

      impl<'a, T> ColumnIterator<'a, T> {
      pub fn new(map: &'a [Vec<T>], column: usize) -> ColumnIterator<'a, T> {
      Self { map, column, i: 0 }
      }
      }

      impl<'a, T> Iterator for ColumnIterator<'a, T> {
      type Item = &'a T;

      fn next(&mut self) -> Option<Self::Item> {
      if self.i >= self.map.len() {
      return None;
      }

      self.i += 1;
      Some(&self.map[self.i - 1][self.column])
      }
      }

      Given this piece of an iterator, it is very easy to factor out the common functionality between the rows and columns into:

      -
      let mut find_boundaries = |constructor: fn(usize) -> Orientation,
      iterator: &mut dyn Iterator<Item = &char>,
      upper_bound,
      i| {
      let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == ' ');
      let start = first_non_empty.next().unwrap().0 as isize;

      let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
      let end = last_non_empty.next().unwrap_or((upper_bound, &'_')).0 as isize;

      boundaries.insert(constructor(i), start..end);
      };
      +
      let mut find_boundaries = |constructor: fn(usize) -> Orientation,
      iterator: &mut dyn Iterator<Item = &char>,
      upper_bound,
      i| {
      let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == ' ');
      let start = first_non_empty.next().unwrap().0 as isize;

      let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
      let end = last_non_empty.next().unwrap_or((upper_bound, &'_')).0 as isize;

      boundaries.insert(constructor(i), start..end);
      };

      And then use it as such:

      -
      // construct all horizontal boundaries
      (0..map.len()).for_each(|row| {
      find_boundaries(
      Orientation::horizontal,
      &mut map[row].iter(),
      map[row].len(),
      row,
      );
      });

      // construct all vertical boundaries
      (0..map[0].len()).for_each(|col| {
      find_boundaries(
      Orientation::vertical,
      &mut ColumnIterator::new(&map, col),
      map.len(),
      col,
      );
      });
      +
      // construct all horizontal boundaries
      (0..map.len()).for_each(|row| {
      find_boundaries(
      Orientation::horizontal,
      &mut map[row].iter(),
      map[row].len(),
      row,
      );
      });

      // construct all vertical boundaries
      (0..map[0].len()).for_each(|col| {
      find_boundaries(
      Orientation::vertical,
      &mut ColumnIterator::new(&map, col),
      map.len(),
      col,
      );
      });

      Walking around the map

      Once the 2nd part got introduced, you start to think about a way how not to copy-paste a lot of stuff (I haven't avoided it anyways…). In this problem, I've chosen to introduce a trait (i.e. interface) for 2D and 3D walker.

      -
      trait Wrap: Clone {
      type State;

      // simulation
      fn is_blocked(&self) -> bool;
      fn step(&mut self, steps: isize);
      fn turn_left(&mut self);
      fn turn_right(&mut self);

      // movement
      fn next(&self) -> (Self::State, Direction);

      // final answer
      fn answer(&self) -> Output;
      }
      +
      trait Wrap: Clone {
      type State;

      // simulation
      fn is_blocked(&self) -> bool;
      fn step(&mut self, steps: isize);
      fn turn_left(&mut self);
      fn turn_right(&mut self);

      // movement
      fn next(&self) -> (Self::State, Direction);

      // final answer
      fn answer(&self) -> Output;
      }

      Each walker maintains its own state and also provides the functions that are used during the simulation. The “promised” methods are separated into:

        @@ -425,7 +425,7 @@ implementation-specific walker

      Both 2D and 3D versions borrow the original input and therefore you must annotate the lifetime of it:

      -
      struct Wrap2D<'a> {
      input: &'a Input,
      position: Position,
      direction: Direction,
      }
      impl<'a> Wrap2D<'a> {
      fn new(input: &'a Input) -> Wrap2D<'a> {
      // …
      +
      struct Wrap2D<'a> {
      input: &'a Input,
      position: Position,
      direction: Direction,
      }
      impl<'a> Wrap2D<'a> {
      fn new(input: &'a Input) -> Wrap2D<'a> {
      // …

      Problems

      I have used a lot of closures for this problem and once I introduced a parameter that was of unknown type (apart from the fact it implements a specific trait), I @@ -442,13 +442,13 @@ of rather smart suggestions.

      char was the .is_digit() function that takes a radix as a parameter. Clippy noticed that I use radix = 10 and suggested switching to .is_ascii_digit() that does exactly the same thing:

      -
      -                .take_while(|c| c.is_digit(10))
      + .take_while(|c| c.is_ascii_digit())
      +
      -                .take_while(|c| c.is_digit(10))
      + .take_while(|c| c.is_ascii_digit())

      Another useful suggestion appeared when working with the iterators and I wanted to get the nn-th element from it. You know the .skip(), you know the .next(), just “slap” them together and we're done for 😁 Well, I got suggested to use .nth() that does exactly the combination of the two mentioned methods on iterators:

      -
      -            match it.clone().skip(skip).next().unwrap() {
      + match it.clone().nth(skip).unwrap() {
      +
      -            match it.clone().skip(skip).next().unwrap() {
      + match it.clone().nth(skip).unwrap() {

      Day 23: Unstable Diffusion

      tl;dr

      Simulating movement of elves around with a set of specific rules.

      Solution

      @@ -461,20 +461,20 @@ minimum that are, of course, exactly the same except for initial values and comparators, it looks like a rather simple fix, but typing in Rust is something else, right? In the end I settled for a function that computes both boundaries without any duplication while using a closure:

      -
      fn get_bounds(positions: &Input) -> (Vector2D<isize>, Vector2D<isize>) {
      let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {
      positions
      .iter()
      .fold(Vector2D::new(init, init), |acc, elf| {
      Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))
      })
      };

      (f(isize::MAX, &min::<isize>), f(isize::MIN, &max::<isize>))
      }
      +
      fn get_bounds(positions: &Input) -> (Vector2D<isize>, Vector2D<isize>) {
      let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {
      positions
      .iter()
      .fold(Vector2D::new(init, init), |acc, elf| {
      Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))
      })
      };

      (f(isize::MAX, &min::<isize>), f(isize::MIN, &max::<isize>))
      }

      This function returns a pair of 2D vectors that represent opposite points of the bounding rectangle of all elves.

      You might ask why would we need a closure and the answer is that positions cannot be captured from within the nested function, only via closure. One more fun fact on top of that is the type of the comparator

      -
      &dyn Fn(isize, isize) -> isize
      +
      &dyn Fn(isize, isize) -> isize

      Once we remove the dyn keyword, compiler yells at us and also includes a way how to get a more thorough explanation of the error by running

      $ rustc --explain E0782

      which shows us

      Trait objects must include the dyn keyword.

      Erroneous code example:

      -
      trait Foo {}
      fn test(arg: Box<Foo>) {} // error!
      +
      trait Foo {}
      fn test(arg: Box<Foo>) {} // error!

      Trait objects are a way to call methods on types that are not known until runtime but conform to some trait.

      Trait objects should be formed with Box<dyn Foo>, but in the code above @@ -482,7 +482,7 @@ runtime but conform to some trait.

      This makes it harder to see that arg is a trait object and not a simply a heap allocated type called Foo.

      To fix this issue, add dyn before the trait name.

      -
      trait Foo {}
      fn test(arg: Box<dyn Foo>) {} // ok!
      +
      trait Foo {}
      fn test(arg: Box<dyn Foo>) {} // ok!

      This used to be allowed before edition 2021, but is now an error.

      Rant

      Not all of the explanations are helpful though, in some cases they might be even more confusing than helpful, since they address very simple use cases.

      As you can see, even in this case there are two sides to the explanations:

        @@ -525,7 +525,7 @@ cleaned it up a bit. The changed version is shown here and the original was just more verbose.

      I'll skip the boring parts of checking bounds and entry/exit of the basin 😉 We can easily calculate positions of the blizzards using a modular arithmetics:

      -
      impl Index<Position> for Basin {
      type Output = char;

      fn index(&self, index: Position) -> &Self::Output {
      // ‹skipped boring parts›

      // We need to account for the loops of the blizzards
      let width = self.cols - 2;
      let height = self.rows - 2;

      let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;
      [
      (
      index.y() as usize,
      blizzard_origin(width, -1, index.z(), index.x()),
      '>',
      ),
      (
      index.y() as usize,
      blizzard_origin(width, 1, index.z(), index.x()),
      '<',
      ),
      (
      blizzard_origin(height, -1, index.z(), index.y()),
      index.x() as usize,
      'v',
      ),
      (
      blizzard_origin(height, 1, index.z(), index.y()),
      index.x() as usize,
      '^',
      ),
      ]
      .iter()
      .find_map(|&(y, x, direction)| {
      if self.map[y][x] == direction {
      Some(&self.map[y][x])
      } else {
      None
      }
      })
      .unwrap_or(&'.')
      }
      }
      +
      impl Index<Position> for Basin {
      type Output = char;

      fn index(&self, index: Position) -> &Self::Output {
      // ‹skipped boring parts›

      // We need to account for the loops of the blizzards
      let width = self.cols - 2;
      let height = self.rows - 2;

      let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;
      [
      (
      index.y() as usize,
      blizzard_origin(width, -1, index.z(), index.x()),
      '>',
      ),
      (
      index.y() as usize,
      blizzard_origin(width, 1, index.z(), index.x()),
      '<',
      ),
      (
      blizzard_origin(height, -1, index.z(), index.y()),
      index.x() as usize,
      'v',
      ),
      (
      blizzard_origin(height, 1, index.z(), index.y()),
      index.x() as usize,
      '^',
      ),
      ]
      .iter()
      .find_map(|&(y, x, direction)| {
      if self.map[y][x] == direction {
      Some(&self.map[y][x])
      } else {
      None
      }
      })
      .unwrap_or(&'.')
      }
      }

      As you can see, there is an expression for calculating the original position and it's used multiple times, so why not take it out to a lambda, right? 😉

      I couldn't get the rustfmt to format the for-loop nicely, so I've just @@ -543,10 +543,10 @@ algorithm, since it better reflects the cost function.

      a priority for the queue.

      Whereas with the A*, I have chosen to use both time and Manhattan distance that promotes vertices closer to the exit and with a minimum time taken.

      Cost function is, of course, a closure 😉

      -
      let cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());
      +
      let cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());

      And also for checking the possible moves from the current vertex, I have implemented, yet another, closure that yields an iterator with the next moves:

      -
      let next_positions = |p| {
      [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]
      .iter()
      .filter_map(move |&(x, y, t)| {
      let next_p = p + Vector3D::new(x, y, t);

      if basin[next_p] == '.' {
      Some(next_p)
      } else {
      None
      }
      })
      };
      +
      let next_positions = |p| {
      [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]
      .iter()
      .filter_map(move |&(x, y, t)| {
      let next_p = p + Vector3D::new(x, y, t);

      if basin[next_p] == '.' {
      Some(next_p)
      } else {
      None
      }
      })
      };

      Min-heap

      In this case I had a need to use the priority queue taking the elements with the lowest cost as the prioritized ones. Rust only offers you the BinaryHeap and @@ -556,7 +556,7 @@ the BinaryHeap). However the wrapping affects the type of the h popping the most prioritized elements yields values wrapped in the Reverse.

      For this purpose I have just taken the max-heap and wrapped it as a whole in a separate structure providing just the desired methods:

      -
      use std::cmp::{Ord, Reverse};
      use std::collections::BinaryHeap;

      pub struct MinHeap<T> {
      heap: BinaryHeap<Reverse<T>>,
      }

      impl<T: Ord> MinHeap<T> {
      pub fn new() -> MinHeap<T> {
      MinHeap {
      heap: BinaryHeap::new(),
      }
      }

      pub fn push(&mut self, item: T) {
      self.heap.push(Reverse(item))
      }

      pub fn pop(&mut self) -> Option<T> {
      self.heap.pop().map(|Reverse(x)| x)
      }
      }

      impl<T: Ord> Default for MinHeap<T> {
      fn default() -> Self {
      Self::new()
      }
      }
      +
      use std::cmp::{Ord, Reverse};
      use std::collections::BinaryHeap;

      pub struct MinHeap<T> {
      heap: BinaryHeap<Reverse<T>>,
      }

      impl<T: Ord> MinHeap<T> {
      pub fn new() -> MinHeap<T> {
      MinHeap {
      heap: BinaryHeap::new(),
      }
      }

      pub fn push(&mut self, item: T) {
      self.heap.push(Reverse(item))
      }

      pub fn pop(&mut self) -> Option<T> {
      self.heap.pop().map(|Reverse(x)| x)
      }
      }

      impl<T: Ord> Default for MinHeap<T> {
      fn default() -> Self {
      Self::new()
      }
      }

      Rest is just the algorithm implementation which is not that interesting.

      Day 25: Full of Hot Air

      tl;dr

      Playing around with a numbers in a special base.

      @@ -573,7 +573,7 @@ with a rather easy solution, as the last day always seems to be.

      that sounds familiar, doesn't it? Let's introduce a structure for the SNAFU numbers and implement the traits that we need.

      Let's start with a structure:

      -
      #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
      struct SNAFU {
      value: i64,
      }
      +
      #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
      struct SNAFU {
      value: i64,
      }

      Converting from &str

      We will start by implementing the FromStr trait that will help us parse our input. This is rather simple, I can just take the from_snafu function, copy-paste it @@ -592,13 +592,13 @@ trait for the SNAFU.

      After those changes we need to adjust the code and tests.

      Parsing of the input is very easy, before we have used the lines, now we parse everything:

      -
           fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
      - file_to_lines(pathname)
      + file_to_structs(pathname)
      }
      +
           fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
      - file_to_lines(pathname)
      + file_to_structs(pathname)
      }

      Part 1 needs to be adjusted a bit too:

      -
           fn part_1(input: &Input) -> Output {
      - to_snafu(input.iter().map(|s| from_snafu(s)).sum())
      + SNAFU::from(input.iter().map(|s| s.value).sum::<i64>()).to_string()
      }
      +
           fn part_1(input: &Input) -> Output {
      - to_snafu(input.iter().map(|s| from_snafu(s)).sum())
      + SNAFU::from(input.iter().map(|s| s.value).sum::<i64>()).to_string()
      }

      You can also see that it simplifies the meaning a bit and it is more explicit than the previous versions.

      And for the tests:

      -
           #[test]
      fn test_from() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(from_snafu(s), *n);
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(s.parse::<SNAFU>().unwrap().value, n);
      }
      }

      #[test]
      fn test_to() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(to_snafu(*n), s.to_string());
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(SNAFU::from(n).to_string(), s.to_string());
      }
      +
           #[test]
      fn test_from() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(from_snafu(s), *n);
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(s.parse::<SNAFU>().unwrap().value, n);
      }
      }

      #[test]
      fn test_to() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(to_snafu(*n), s.to_string());
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(SNAFU::from(n).to_string(), s.to_string());
      }

      Summary

      Let's wrap the whole thing up! Keeping in mind both AoC and the Rust…

      Finished advent calendar :smile:

      @@ -664,7 +664,7 @@ to implement the indexing in a graph, rather than explicitly access the underlying data structure.

      Here you can see a rather short snippet from the solution that allows you to “index” the graph:

      -
      impl Index<&str> for Graph {
      type Output = Vertex;

      fn index(&self, index: &str) -> &Self::Output {
      &self.g[index]
      }
      }
      +
      impl Index<&str> for Graph {
      type Output = Vertex;

      fn index(&self, index: &str) -> &Self::Output {
      &self.g[index]
      }
      }

      Cartesian product

      During the implementation I had to utilize Floyd-Warshall algorithm for finding the shortest path between pairs of vertices and utilized the iproduct! macro @@ -678,7 +678,7 @@ also makes it harder to evaluate algorithmically, since you need to check the different ways the work can be split.

      Being affected by functional programming brain damage™️, I have chosen to do this part by function that returns an iterator over the possible ways:

      -
      fn pairings(
      valves: &BTreeSet<String>,
      ) -> impl Iterator<Item = (BTreeSet<String>, BTreeSet<String>)> + '_ {
      let mapping = valves.iter().collect_vec();

      let max_mask = 1 << (valves.len() - 1);

      (0..max_mask).map(move |mask| {
      let mut elephant = BTreeSet::new();
      let mut human = BTreeSet::new();

      for (i, &v) in mapping.iter().enumerate() {
      if (mask & (1 << i)) == 0 {
      human.insert(v.clone());
      } else {
      elephant.insert(v.clone());
      }
      }

      (human, elephant)
      })
      }
      +
      fn pairings(
      valves: &BTreeSet<String>,
      ) -> impl Iterator<Item = (BTreeSet<String>, BTreeSet<String>)> + '_ {
      let mapping = valves.iter().collect_vec();

      let max_mask = 1 << (valves.len() - 1);

      (0..max_mask).map(move |mask| {
      let mut elephant = BTreeSet::new();
      let mut human = BTreeSet::new();

      for (i, &v) in mapping.iter().enumerate() {
      if (mask & (1 << i)) == 0 {
      human.insert(v.clone());
      } else {
      elephant.insert(v.clone());
      }
      }

      (human, elephant)
      })
      }

      Day 17: Pyroclastic Flow

      tl;dr

      Simulating an autonomous Tetris where pieces get affected by a series of jets of hot gas.

      @@ -689,7 +689,7 @@ hot gas.

      iterate through the positions that can actually collide with the wall or other piece.

      To get the desired behaviour, you can just compose few smaller functions:

      -
      fn occupied(shape: &[Vec<char>]) -> impl Iterator<Item = Position> + '_ {
      shape.iter().enumerate().flat_map(|(y, row)| {
      row.iter().enumerate().filter_map(move |(x, c)| {
      if c == &'#' {
      Some(Vector2D::new(x as isize, y as isize))
      } else {
      None
      }
      })
      })
      }
      +
      fn occupied(shape: &[Vec<char>]) -> impl Iterator<Item = Position> + '_ {
      shape.iter().enumerate().flat_map(|(y, row)| {
      row.iter().enumerate().filter_map(move |(x, c)| {
      if c == &'#' {
      Some(Vector2D::new(x as isize, y as isize))
      } else {
      None
      }
      })
      })
      }

      In the end, we get relative positions which we can adjust later when given the specific positions from iterator. You can see some interesting parts in this:

        @@ -708,7 +708,7 @@ and also unwraps the values from Some(…). jets that move our pieces around. Initially I have implemented my own infinite iterator that just yields the indices. It is a very simple, yet powerful, piece of code:

        -
        struct InfiniteIndex {
        size: usize,
        i: usize,
        }

        impl InfiniteIndex {
        fn new(size: usize) -> InfiniteIndex {
        InfiniteIndex { size, i: size - 1 }
        }
        }

        impl Iterator for InfiniteIndex {
        type Item = usize;

        fn next(&mut self) -> Option<Self::Item> {
        self.i = (self.i + 1) % self.size;
        Some(self.i)
        }
        }
        +
        struct InfiniteIndex {
        size: usize,
        i: usize,
        }

        impl InfiniteIndex {
        fn new(size: usize) -> InfiniteIndex {
        InfiniteIndex { size, i: size - 1 }
        }
        }

        impl Iterator for InfiniteIndex {
        type Item = usize;

        fn next(&mut self) -> Option<Self::Item> {
        self.i = (self.i + 1) % self.size;
        Some(self.i)
        }
        }

        However when I'm looking at the code now, it doesn't really make much sense… Guess what, we can use a built-in function that is implemented on iterators for that! The function is called .cycle()

        @@ -754,13 +754,13 @@ the Rc<RefCell<T>>. In the end I failed on wrong an a rather interesting issue with .borrow_mut() method being used on Rc<RefCell<T>>.

        .borrow_mut()

        Consider the following snippet of the code (taken from the documentation):

        -
        use std::cell::{RefCell, RefMut};
        use std::collections::HashMap;
        use std::rc::Rc;
        // use std::borrow::BorrowMut;

        fn main() {
        let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
        // Create a new block to limit the scope of the dynamic borrow
        {
        let mut map: RefMut<_> = shared_map.borrow_mut();
        map.insert("africa", 92388);
        map.insert("kyoto", 11837);
        map.insert("piccadilly", 11826);
        map.insert("marbles", 38);
        }

        // Note that if we had not let the previous borrow of the cache fall out
        // of scope then the subsequent borrow would cause a dynamic thread panic.
        // This is the major hazard of using `RefCell`.
        let total: i32 = shared_map.borrow().values().sum();
        println!("{total}");
        }
        +
        use std::cell::{RefCell, RefMut};
        use std::collections::HashMap;
        use std::rc::Rc;
        // use std::borrow::BorrowMut;

        fn main() {
        let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
        // Create a new block to limit the scope of the dynamic borrow
        {
        let mut map: RefMut<_> = shared_map.borrow_mut();
        map.insert("africa", 92388);
        map.insert("kyoto", 11837);
        map.insert("piccadilly", 11826);
        map.insert("marbles", 38);
        }

        // Note that if we had not let the previous borrow of the cache fall out
        // of scope then the subsequent borrow would cause a dynamic thread panic.
        // This is the major hazard of using `RefCell`.
        let total: i32 = shared_map.borrow().values().sum();
        println!("{total}");
        }

        We allocate a hash map on the heap and then in the inner block, we borrow it as a mutable reference, so that we can use it.

        note

        It is a very primitive example for Rc<RefCell<T>> and mutable borrow.

        If you uncomment the 4th line with use std::borrow::BorrowMut;, you cannot compile the code anymore, because of

        -
           Compiling playground v0.0.1 (/playground)
        error[E0308]: mismatched types
        --> src/main.rs:10:34
        |
        10 | let mut map: RefMut<_> = shared_map.borrow_mut();
        | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference
        | |
        | expected due to this
        |
        = note: expected struct `RefMut<'_, _>`
        found mutable reference `&mut Rc<RefCell<HashMap<_, _>>>`

        error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
        --> src/main.rs:11:13
        |
        11 | map.insert("africa", 92388);
        | ^^^^^^ method not found in `RefMut<'_, _>`

        error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
        --> src/main.rs:12:13
        |
        12 | map.insert("kyoto", 11837);
        | ^^^^^^ method not found in `RefMut<'_, _>`

        error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
        --> src/main.rs:13:13
        |
        13 | map.insert("piccadilly", 11826);
        | ^^^^^^ method not found in `RefMut<'_, _>`

        error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
        --> src/main.rs:14:13
        |
        14 | map.insert("marbles", 38);
        | ^^^^^^ method not found in `RefMut<'_, _>`

        Some errors have detailed explanations: E0308, E0599.
        For more information about an error, try `rustc --explain E0308`.
        error: could not compile `playground` due to 5 previous errors
        +
           Compiling playground v0.0.1 (/playground)
        error[E0308]: mismatched types
        --> src/main.rs:10:34
        |
        10 | let mut map: RefMut<_> = shared_map.borrow_mut();
        | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference
        | |
        | expected due to this
        |
        = note: expected struct `RefMut<'_, _>`
        found mutable reference `&mut Rc<RefCell<HashMap<_, _>>>`

        error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
        --> src/main.rs:11:13
        |
        11 | map.insert("africa", 92388);
        | ^^^^^^ method not found in `RefMut<'_, _>`

        error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
        --> src/main.rs:12:13
        |
        12 | map.insert("kyoto", 11837);
        | ^^^^^^ method not found in `RefMut<'_, _>`

        error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
        --> src/main.rs:13:13
        |
        13 | map.insert("piccadilly", 11826);
        | ^^^^^^ method not found in `RefMut<'_, _>`

        error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
        --> src/main.rs:14:13
        |
        14 | map.insert("marbles", 38);
        | ^^^^^^ method not found in `RefMut<'_, _>`

        Some errors have detailed explanations: E0308, E0599.
        For more information about an error, try `rustc --explain E0308`.
        error: could not compile `playground` due to 5 previous errors

        It might seem a bit ridiculous. However, I got to a point where the compiler suggested use std::borrow::BorrowMut; and it resulted in breaking parts of the code that worked previously. I think it may be a good idea to go over what is @@ -787,14 +787,14 @@ method. OK, but how can we call it on the Rc<T>? Easily! I have not been able to find a lot on this trait. My guess is that it provides a method instead of a syntactic sugar (&mut x) for the mutable borrow. And also it provides default implementations for the types:

        -
        impl BorrowMut<str> for String

        impl<T> BorrowMut<T> for &mut T
        where
        T: ?Sized,

        impl<T> BorrowMut<T> for T
        where
        T: ?Sized,

        impl<T, A> BorrowMut<[T]> for Vec<T, A>
        where
        A: Allocator,

        impl<T, A> BorrowMut<T> for Box<T, A>
        where
        A: Allocator,
        T: ?Sized,

        impl<T, const N: usize> BorrowMut<[T]> for [T; N]
        +
        impl BorrowMut<str> for String

        impl<T> BorrowMut<T> for &mut T
        where
        T: ?Sized,

        impl<T> BorrowMut<T> for T
        where
        T: ?Sized,

        impl<T, A> BorrowMut<[T]> for Vec<T, A>
        where
        A: Allocator,

        impl<T, A> BorrowMut<T> for Box<T, A>
        where
        A: Allocator,
        T: ?Sized,

        impl<T, const N: usize> BorrowMut<[T]> for [T; N]
        Conflict

        Now the question is why did it break the code… My first take was that the type Rc<RefCell<T>> has some specialized implementation of the .borrow_mut() and the use overrides it with the default, which is true in a sense. However there is no specialized implementation. Let's have a look at the trait and the type signature on the RefCell<T>:

        -
        // trait
        pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
        where
        Borrowed: ?Sized,
        {
        fn borrow_mut(&mut self) -> &mut Borrowed;
        }

        // ‹RefCell<T>.borrow_mut()› type signature
        pub fn borrow_mut(&self) -> RefMut<'_, T>
        +
        // trait
        pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
        where
        Borrowed: ?Sized,
        {
        fn borrow_mut(&mut self) -> &mut Borrowed;
        }

        // ‹RefCell<T>.borrow_mut()› type signature
        pub fn borrow_mut(&self) -> RefMut<'_, T>

        I think that we can definitely agree on the fact that RefMut<'_, T> is not the RefCell<T>.

        In my opinion, RefCell<T> implements a separate .borrow_mut() rather @@ -821,7 +821,7 @@ as:

        that you can use the macro machinery to save yourself some typing. If you have enumeration of which the default value doesn't bear any parameter, you can just do2:

        -
        #[derive(Default)]
        enum Color {
        #[default]
        White,
        Gray,
        Black,
        }
        +
        #[derive(Default)]
        enum Color {
        #[default]
        White,
        Gray,
        Black,
        }

        Abusing negation

        If you want to use a unary minus operator on your own type, you can implement a Neg trait3. I was dealing with a binary tree and needed a way how to look @@ -872,26 +872,26 @@ order and return the resulting matrix.

        Image describing the problem

        Skeleton and initial adjustments

        We are given the following skeleton for the C++ and the given challenge:

        -
        class Solution {
        public:
        vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {

        }
        };
        +
        class Solution {
        public:
        vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {

        }
        };

        The task is to sort the passed matrix diagonally and then return it. First of all, I don't like to solve this in a web browser, so we'll need to adjust it accordingly for running it locally. We'll start by including the vector header and using fully-qualified namespaces1 and also adding few tests:

        -
        #include <cassert>
        #include <vector>

        using matrix = std::vector<std::vector<int>>;

        class Solution {
        public:
        matrix diagonalSort(matrix& mat)
        {
        }
        };

        static void test_case_1()
        {
        // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
        // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]

        Solution s;
        assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
        std::vector { 2, 2, 1, 2 },
        std::vector { 1, 1, 1, 2 } })
        == std::vector { std::vector { 1, 1, 1, 1 },
        std::vector { 1, 2, 2, 2 },
        std::vector { 1, 2, 3, 3 } }));
        }

        static void test_case_2()
        {
        // Input: mat =
        // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
        // Output:
        // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]

        Solution s;
        assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
        std::vector { 23, 55, 17, 45, 15, 52 },
        std::vector { 75, 31, 36, 44, 58, 8 },
        std::vector { 22, 27, 33, 25, 68, 4 },
        std::vector { 84, 28, 14, 11, 5, 50 } })
        == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
        std::vector { 11, 11, 25, 45, 8, 69 },
        std::vector { 14, 23, 25, 44, 58, 15 },
        std::vector { 22, 27, 31, 36, 50, 66 },
        std::vector { 84, 28, 75, 33, 55, 68 } }));
        }

        int main()
        {
        test_case_1();
        test_case_2();

        return 0;
        }
        +
        #include <cassert>
        #include <vector>

        using matrix = std::vector<std::vector<int>>;

        class Solution {
        public:
        matrix diagonalSort(matrix& mat)
        {
        }
        };

        static void test_case_1()
        {
        // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
        // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]

        Solution s;
        assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
        std::vector { 2, 2, 1, 2 },
        std::vector { 1, 1, 1, 2 } })
        == std::vector { std::vector { 1, 1, 1, 1 },
        std::vector { 1, 2, 2, 2 },
        std::vector { 1, 2, 3, 3 } }));
        }

        static void test_case_2()
        {
        // Input: mat =
        // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
        // Output:
        // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]

        Solution s;
        assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
        std::vector { 23, 55, 17, 45, 15, 52 },
        std::vector { 75, 31, 36, 44, 58, 8 },
        std::vector { 22, 27, 33, 25, 68, 4 },
        std::vector { 84, 28, 14, 11, 5, 50 } })
        == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
        std::vector { 11, 11, 25, 45, 8, 69 },
        std::vector { 14, 23, 25, 44, 58, 15 },
        std::vector { 22, 27, 31, 36, 50, 66 },
        std::vector { 84, 28, 75, 33, 55, 68 } }));
        }

        int main()
        {
        test_case_1();
        test_case_2();

        return 0;
        }

        We need to return the matrix, but we're given a reference to the input matrix. We can easily abuse the C++ here and just switch the reference to value, this way the matrix will be copied when passed to the function, we can sort the copy and just return it back. And we also get yelled by the compiler for the fact that the method doesn't return anything yet, so to make it “shut up” we will just return the input for now:

        -
        -    matrix diagonalSort(matrix& mat)
        + matrix diagonalSort(matrix mat)
        {
        + return mat;
        }
        +
        -    matrix diagonalSort(matrix& mat)
        + matrix diagonalSort(matrix mat)
        {
        + return mat;
        }

        Now, we get the copy and we're good to go.

        Naïve solution

        As you may know, C++ offers a plethora of functions that can be used to your advantage, given that you know how to “bend” the data structures accordingly.

        What does that mean for us? Well, we have an std::sort, we can use it, right? Let's have a look at it:

        -
        template< class RandomIt >
        void sort( RandomIt first, RandomIt last );
        +
        template< class RandomIt >
        void sort( RandomIt first, RandomIt last );

        This overload is more than we need. What does it do? It just sorts the elements in the range [first, last) using operator< on them. We can't sort the whole matrix using this, but… we can sort just »one« diagonal without doing much work @@ -909,10 +909,10 @@ up, i.e. “compiler-assisted development3. And that way we get

        -
        matrix diagonalSort(matrix mat)
        {
        // we iterate over the diagonals
        for (auto d : diagonals(mat)) {
        // and we sort each diagonal
        std::sort(d.begin(), d.end());
        }

        // we take the matrix by copy, so we can sort in-situ and return the copy
        // that we sorted
        return mat;
        }
        +
        matrix diagonalSort(matrix mat)
        {
        // we iterate over the diagonals
        for (auto d : diagonals(mat)) {
        // and we sort each diagonal
        std::sort(d.begin(), d.end());
        }

        // we take the matrix by copy, so we can sort in-situ and return the copy
        // that we sorted
        return mat;
        }

        This solution looks very simple, doesn't it? Well, cause it is. Let's try compiling it:

        -
        matrix-sort.cpp:11:23: error: use of undeclared identifier 'diagonals' [clang-diagnostic-error]
        for (auto d : diagonals(mat)) {
        ^
        Found compiler error(s).
        make: *** [makefile:14: tidy] Error 1
        +
        matrix-sort.cpp:11:23: error: use of undeclared identifier 'diagonals' [clang-diagnostic-error]
        for (auto d : diagonals(mat)) {
        ^
        Found compiler error(s).
        make: *** [makefile:14: tidy] Error 1

        OK, seems about right. We haven't implemented the diagonals yet. And based on what we've written so far, we need a function or a class diagonals that will give us the diagonals we need.

        @@ -927,7 +927,7 @@ do such functionality for a matrix of any type, not just the int fr
      • get the beginning
      • get the end (the “sentinel”)
      -
      template <typename T>
      class diagonals {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& _matrix;

      public:
      diagonals(matrix_t& m)
      : _matrix(m)
      {
      }
      diagonals_iter begin()
      {
      /* TODO */
      }
      diagonals_iter end()
      {
      /* TODO */
      }
      };
      +
      template <typename T>
      class diagonals {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& _matrix;

      public:
      diagonals(matrix_t& m)
      : _matrix(m)
      {
      }
      diagonals_iter begin()
      {
      /* TODO */
      }
      diagonals_iter end()
      {
      /* TODO */
      }
      };

      Now we have a diagonals that we can use to go through the diagonals. We haven't implemented the core of it yet. Let's go through what we have for now.

      We have a templated class with templated T that is used as a placeholder for any @@ -946,7 +946,7 @@ in the first row, followed by the rest of the diagonals in the first column.

      need to know which diagonal is next. For that purpose we will pass the indices of the first cell on the diagonal. That way we can always tell how to move forward.

      We will start by updating the begin and end to reflect our choice accordingly.

      -
      diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
      diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }
      +
      diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
      diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }

      For the begin we return the first diagonal that starts at (0, 0). And because we have decided to do the diagonals in the first column at the end, the first diagonal that is not a valid one is the one at (0, height). Apart from the @@ -960,7 +960,7 @@ don't care about the fact they don't need to be sorted.

      We can start with a simple skeleton based on the information that we pass from the diagonals. Also to utilize the matrix_t and also contain implementation details hidden away, we will put this code into the diagonals class.

      -
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }
      };
      +
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }
      };

      In this case we will be implementing a “simple” forward iterator, so we don't need to implement a lot. Notably it will be:

        @@ -970,12 +970,12 @@ iterate over)
      • dereference operator (we need to be able to retrieve the objects we iterate over)
      -
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator!=(const diagonals_iter& rhs) const
      {
      // iterators are not equal if they reference different matrices, or
      // their positions differ
      return m != rhs.m || x != rhs.x || y != rhs.y;
      }

      diagonals_iter& operator++()
      {
      if (y != 0) {
      // iterating through diagonals down the first column
      y++;
      return *this;
      }

      // iterating the diagonals along the first row
      x++;
      if (x == m.front().size()) {
      // switching to diagonals in the first column
      x = 0;
      y++;
      }

      return *this;
      }

      diagonal<T> operator*() const { return diagonal { m, x, y }; }
      };
      +
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator!=(const diagonals_iter& rhs) const
      {
      // iterators are not equal if they reference different matrices, or
      // their positions differ
      return m != rhs.m || x != rhs.x || y != rhs.y;
      }

      diagonals_iter& operator++()
      {
      if (y != 0) {
      // iterating through diagonals down the first column
      y++;
      return *this;
      }

      // iterating the diagonals along the first row
      x++;
      if (x == m.front().size()) {
      // switching to diagonals in the first column
      x = 0;
      y++;
      }

      return *this;
      }

      diagonal<T> operator*() const { return diagonal { m, x, y }; }
      };

      Let's go one-by-one. Inequality operator is rather simple, just compare iterator's attributes field-by-field. If you think about it, checking inequality of two 2D vectors may be a bit inefficient, therefore, we can swap around and check it as a last thing.

      -
      -        return m != rhs.m || x != rhs.x || y != rhs.y;
      + return x != rhs.x || y != rhs.y || m != rhs.m;
      +
      -        return m != rhs.m || x != rhs.x || y != rhs.y;
      + return x != rhs.x || y != rhs.y || m != rhs.m;

      Preincrementation is where the magic happens. If you have a better look, you can see two branches of this operation:

        @@ -995,7 +995,7 @@ something else. In our case it will be a class called diagonal.

        a diagonal is the matrix itself and the “start” of the diagonal (row and column). And we also know that the diagonal must provide some iterators for the std::sort function. We can start with the following skeleton:

        -
        template <typename T>
        class diagonal {
        using matrix_t = std::vector<std::vector<T>>;

        matrix_t& matrix;
        std::size_t x;
        std::size_t y;

        public:
        diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
        : matrix(matrix)
        , x(x)
        , y(y)
        {
        }

        diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }

        diagonal_iter end() const
        {
        auto max_x = matrix[y].size();
        auto max_y = matrix.size();

        // we need to find the distance in which we get out of bounds (either in
        // column or row)
        auto steps = std::min(max_x - x, max_y - y);

        return diagonal_iter { matrix, x + steps, y + steps };
        }
        };
        +
        template <typename T>
        class diagonal {
        using matrix_t = std::vector<std::vector<T>>;

        matrix_t& matrix;
        std::size_t x;
        std::size_t y;

        public:
        diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
        : matrix(matrix)
        , x(x)
        , y(y)
        {
        }

        diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }

        diagonal_iter end() const
        {
        auto max_x = matrix[y].size();
        auto max_y = matrix.size();

        // we need to find the distance in which we get out of bounds (either in
        // column or row)
        auto steps = std::min(max_x - x, max_y - y);

        return diagonal_iter { matrix, x + steps, y + steps };
        }
        };

        Initialization is rather simple, we just “keep” the stuff we get, begin is the simplest, we just delegate.

        In case of the end, it gets more complicated. We need to know where is the “end” @@ -1022,7 +1022,7 @@ be used in std::sort. We need the usual operations like:

    We will also add all the types that our iterator uses with the category of the iterator, i.e. what interface it supports:

    -
    class diagonal_iter {
    // we need to keep reference to the matrix itself
    matrix_t& m;

    // we need to be able to tell our current position
    std::size_t x;
    std::size_t y;

    public:
    using difference_type = std::ptrdiff_t;
    using value_type = T;
    using pointer = T*;
    using reference = T&;
    using iterator_category = std::random_access_iterator_tag;

    diagonal_iter(matrix_t& matrix,
    std::size_t x,
    std::size_t y)
    : m(matrix)
    , x(x)
    , y(y)
    {
    }

    bool operator==(const diagonal_iter& rhs) const
    {
    return x == rhs.x && y == rhs.y && m == rhs.m;
    }

    diagonal_iter& operator++()
    {
    // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
    // the same time
    x++;
    y++;
    return *this;
    }

    reference operator*() const { return m[y][x]; }
    };
    +
    class diagonal_iter {
    // we need to keep reference to the matrix itself
    matrix_t& m;

    // we need to be able to tell our current position
    std::size_t x;
    std::size_t y;

    public:
    using difference_type = std::ptrdiff_t;
    using value_type = T;
    using pointer = T*;
    using reference = T&;
    using iterator_category = std::random_access_iterator_tag;

    diagonal_iter(matrix_t& matrix,
    std::size_t x,
    std::size_t y)
    : m(matrix)
    , x(x)
    , y(y)
    {
    }

    bool operator==(const diagonal_iter& rhs) const
    {
    return x == rhs.x && y == rhs.y && m == rhs.m;
    }

    diagonal_iter& operator++()
    {
    // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
    // the same time
    x++;
    y++;
    return *this;
    }

    reference operator*() const { return m[y][x]; }
    };

    This is pretty similar to the previous iterator, but now we need to implement the remaining requirements of the random access iterator. Let's see what those are:

      @@ -1033,16 +1033,16 @@ remaining requirements of the random access iterator. Let's see what th
    • define an ordering on the iterators

    Let's fill them in:

    -
    class diagonal_iter {
    // we need to keep reference to the matrix itself
    matrix_t& m;

    // we need to be able to tell our current position
    std::size_t x;
    std::size_t y;

    public:
    using difference_type = std::ptrdiff_t;
    using value_type = T;
    using pointer = T*;
    using reference = T&;
    using iterator_category = std::random_access_iterator_tag;

    diagonal_iter(matrix_t& matrix,
    std::size_t x,
    std::size_t y)
    : m(matrix)
    , x(x)
    , y(y)
    {
    }

    bool operator==(const diagonal_iter& rhs) const
    {
    return x == rhs.x && y == rhs.y && m == rhs.m;
    }

    diagonal_iter& operator++()
    {
    // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
    // the same time
    x++;
    y++;
    return *this;
    }

    reference operator*() const { return m[y][x]; }

    // exactly opposite to the incrementation
    diagonal_iter operator--()
    {
    x--;
    y--;
    return *this;
    }

    // moving ‹n› steps back is same as calling decrementation ‹n›-times, so we
    // can just return a new iterator and subtract ‹n› from both coordinates in
    // the matrix
    diagonal_iter operator-(difference_type n) const
    {
    return diagonal_iter { m, x - n, y - n };
    }

    // here we assume that we are given two iterators on the same diagonal
    difference_type operator-(const diagonal_iter& rhs) const
    {
    assert(m == rhs.m);
    return x - rhs.x;
    }

    // counterpart of moving ‹n› steps backwards
    diagonal_iter operator+(difference_type n) const
    {
    return diagonal_iter { m, x + n, y + n };
    }

    // we compare the coordinates, and also assume that those 2 iterators are
    // lying on the same diagonal
    bool operator<(const diagonal_iter& rhs) const
    {
    assert(m == rhs.m);
    return x < rhs.x && y < rhs.y;
    }
    };
    +
    class diagonal_iter {
    // we need to keep reference to the matrix itself
    matrix_t& m;

    // we need to be able to tell our current position
    std::size_t x;
    std::size_t y;

    public:
    using difference_type = std::ptrdiff_t;
    using value_type = T;
    using pointer = T*;
    using reference = T&;
    using iterator_category = std::random_access_iterator_tag;

    diagonal_iter(matrix_t& matrix,
    std::size_t x,
    std::size_t y)
    : m(matrix)
    , x(x)
    , y(y)
    {
    }

    bool operator==(const diagonal_iter& rhs) const
    {
    return x == rhs.x && y == rhs.y && m == rhs.m;
    }

    diagonal_iter& operator++()
    {
    // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
    // the same time
    x++;
    y++;
    return *this;
    }

    reference operator*() const { return m[y][x]; }

    // exactly opposite to the incrementation
    diagonal_iter operator--()
    {
    x--;
    y--;
    return *this;
    }

    // moving ‹n› steps back is same as calling decrementation ‹n›-times, so we
    // can just return a new iterator and subtract ‹n› from both coordinates in
    // the matrix
    diagonal_iter operator-(difference_type n) const
    {
    return diagonal_iter { m, x - n, y - n };
    }

    // here we assume that we are given two iterators on the same diagonal
    difference_type operator-(const diagonal_iter& rhs) const
    {
    assert(m == rhs.m);
    return x - rhs.x;
    }

    // counterpart of moving ‹n› steps backwards
    diagonal_iter operator+(difference_type n) const
    {
    return diagonal_iter { m, x + n, y + n };
    }

    // we compare the coordinates, and also assume that those 2 iterators are
    // lying on the same diagonal
    bool operator<(const diagonal_iter& rhs) const
    {
    assert(m == rhs.m);
    return x < rhs.x && y < rhs.y;
    }
    };

    At this point we could probably try and compile it, right? If we do so, we will get yelled at by a compiler for the following reasons:

    -
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
    __last = __next;
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization 'std::__unguarded_linear_insert<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>' requested here
    std::__unguarded_linear_insert(__i,
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization 'std::__insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__final_insertion_sort(__first, __last, __comp);
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
    ^
    matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
    std::sort(d.begin(), d.end());
    ^
    matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
    matrix_t& m;
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to '__unguarded_linear_insert' [clang-diagnostic-error]
    std::__unguarded_linear_insert(__i,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization 'std::__unguarded_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__final_insertion_sort(__first, __last, __comp);
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
    ^
    matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
    std::sort(d.begin(), d.end());
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal<int>::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]
    __unguarded_linear_insert(_RandomAccessIterator __last,
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
    __last = __cut;
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization 'std::__introsort_loop<diagonal<int>::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__introsort_loop(__first, __last,
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
    ^
    matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
    std::sort(d.begin(), d.end());
    ^
    matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
    matrix_t& m;
    ^
    +
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
    __last = __next;
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization 'std::__unguarded_linear_insert<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>' requested here
    std::__unguarded_linear_insert(__i,
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization 'std::__insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__final_insertion_sort(__first, __last, __comp);
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
    ^
    matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
    std::sort(d.begin(), d.end());
    ^
    matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
    matrix_t& m;
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to '__unguarded_linear_insert' [clang-diagnostic-error]
    std::__unguarded_linear_insert(__i,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization 'std::__unguarded_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__final_insertion_sort(__first, __last, __comp);
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
    ^
    matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
    std::sort(d.begin(), d.end());
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal<int>::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]
    __unguarded_linear_insert(_RandomAccessIterator __last,
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
    __last = __cut;
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization 'std::__introsort_loop<diagonal<int>::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__introsort_loop(__first, __last,
    ^
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
    std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
    ^
    matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
    std::sort(d.begin(), d.end());
    ^
    matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
    matrix_t& m;
    ^

    That's a lot of noise, isn't it? Let's focus on the important parts:

    -
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]

    matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
    matrix_t& m;
    ^
    +
    /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]

    matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
    matrix_t& m;
    ^

    Ah! We have a reference in our iterator, and this prevents us from having a copy assignment operator (that is used “somewhere” in the sorting algorithm). Well… Let's just wrap it!

    -
    # we need to keep a different type than reference
    - matrix_t& m;
    + std::reference_wrapper<matrix_t> m;

    # in comparison we need to get the reference out of the wrapper first
    - return x == rhs.x && y == rhs.y && m == rhs.m;
    + return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();

    # same when we return a reference to the “cell” in the matrix
    - reference operator*() const { return m[y][x]; }
    + reference operator*() const { return m.get()[y][x]; }

    # and finally in the assertions that we set for the “distance” and “less than”
    - assert(m == rhs.m);
    + assert(m.get() == rhs.m.get());
    +
    # we need to keep a different type than reference
    - matrix_t& m;
    + std::reference_wrapper<matrix_t> m;

    # in comparison we need to get the reference out of the wrapper first
    - return x == rhs.x && y == rhs.y && m == rhs.m;
    + return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();

    # same when we return a reference to the “cell” in the matrix
    - reference operator*() const { return m[y][x]; }
    + reference operator*() const { return m.get()[y][x]; }

    # and finally in the assertions that we set for the “distance” and “less than”
    - assert(m == rhs.m);
    + assert(m.get() == rhs.m.get());

    We're done now! We have written an iterator over diagonals for a 2D vector. You can have a look at the final result here.

    Footnotes

      @@ -1096,7 +1096,7 @@ own “box of hell”.

    Swapping indices

    Relatively simple implementation, just take the values, swap them and return new vector.

    -
    impl<T: Copy> Vector2D<T> {
    pub fn swap(&self) -> Self {
    Self {
    x: self.y,
    y: self.x,
    }
    }
    }
    +
    impl<T: Copy> Vector2D<T> {
    pub fn swap(&self) -> Self {
    Self {
    x: self.y,
    y: self.x,
    }
    }
    }

    Pretty straight-forward implementation, but let's talk about the T: Copy. We need to use it, since we are returning a new vector, with swapped values. If we had values that cannot be copied, the only thing we could do, would be a @@ -1105,7 +1105,7 @@ later on). This is pretty similar with the operations on sets from the first wee

    Indexing Vec

    I will start with the indexing, cause bound-checking is a bit more… complicated than I would like to.

    -
    pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }
    +
    pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }

    Let's talk about this mess… Body of the function is probably the most easy part and should not be hard to understand, we just take the x and y and convert them both to usize type that can be used later on for indexing.

    @@ -1144,20 +1144,20 @@ taken by a reference, i.e. returned reference must live at least as long as the

    First issue that our implementation has is the fact that we cannot get a mutable reference out of that function. This could be easily resolved by introducing new function, e.g. index_mut. Which I have actually done while writing this part:

    -
    pub fn index_mut<'a, T, U>(v: &'a mut [Vec<U>], idx: &Vector2D<T>) -> &'a mut U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &mut v[y][x]
    }
    +
    pub fn index_mut<'a, T, U>(v: &'a mut [Vec<U>], idx: &Vector2D<T>) -> &'a mut U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &mut v[y][x]
    }
    «↯» Why can't we use one function?

    When we consider a Vec<T>, we don't need to consider containers as T, Rust implements indexing as traits Index<T> and IndexMut<T> that do the dirty work behind syntactic sugar of container[idx].

    However, implementing of traits is not allowed for external types, i.e. types that you haven't defined yourself. This means that you can implement indexing over containers that you have implemented yourself, but you cannot use your own types for indexing “built-in” types.

    Another part of this rabbit hole is trait SliceIndex<T> that is of a relevance -because of

    impl<T, I> Index<I> for [T]
    where
    I: SliceIndex<[T]>

    impl<T, I, A> Index<I> for Vec<T, A>
    where
    I: SliceIndex<[T]>,
    A: Allocator

    impl<T, I, const N: usize> Index<I> for [T; N]
    where
    [T]: Index<I>

    In other words, if your type implements SliceIndex<T> trait, it can be used +because of

    impl<T, I> Index<I> for [T]
    where
    I: SliceIndex<[T]>

    impl<T, I, A> Index<I> for Vec<T, A>
    where
    I: SliceIndex<[T]>,
    A: Allocator

    impl<T, I, const N: usize> Index<I> for [T; N]
    where
    [T]: Index<I>

    In other words, if your type implements SliceIndex<T> trait, it can be used for indexing. As of now, this trait has all of its required methods experimental and is marked as unsafe.

    Another problem is a requirement for indexing either [Vec<T>] or Vec<Vec<T>>. This requirement could be countered by removing inner type Vec<T> and constraining it by a trait Index (or IndexMut respectively) in a following way

    -
    pub fn index<'a, C, T>(v: &'a [C], idx: &Vector2D<T>) -> &'a C::Output
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    C: Index<usize>
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }
    +
    pub fn index<'a, C, T>(v: &'a [C], idx: &Vector2D<T>) -> &'a C::Output
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    C: Index<usize>
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }

    Given this, we can also give a more meaningful typename for indexing type, such as I.

    Checking bounds

    @@ -1168,12 +1168,12 @@ up with negative values which, unlike in C++, causes an error (instead of underf that you can use to your advantage; you can easily guess how).

    So how can we approach this then? Well… we will convert the bounds instead of the indices and that lead us to:

    -
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    usize: TryInto<T>,
    <usize as TryInto<T>>::Error: Debug,
    T: PartialOrd + Copy,
    {
    idx.y >= 0.try_into().unwrap()
    && idx.y < v.len().try_into().unwrap()
    && idx.x >= 0.try_into().unwrap()
    && idx.x
    < v[TryInto::<usize>::try_into(idx.y).unwrap()]
    .len()
    .try_into()
    .unwrap()
    }
    +
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    usize: TryInto<T>,
    <usize as TryInto<T>>::Error: Debug,
    T: PartialOrd + Copy,
    {
    idx.y >= 0.try_into().unwrap()
    && idx.y < v.len().try_into().unwrap()
    && idx.x >= 0.try_into().unwrap()
    && idx.x
    < v[TryInto::<usize>::try_into(idx.y).unwrap()]
    .len()
    .try_into()
    .unwrap()
    }

    You can tell that it's definitely a shitty code. Let's improve it now! We will get back to the original idea, but do it better. We know that we cannot convert negative values into usize, but we also know that conversion like that returns a Result<T, E> which we can use to our advantage.

    -
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    T: Copy,
    usize: TryFrom<T>,
    {
    usize::try_from(idx.y)
    .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))
    .unwrap_or(false)
    }
    +
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    T: Copy,
    usize: TryFrom<T>,
    {
    usize::try_from(idx.y)
    .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))
    .unwrap_or(false)
    }

    Result<T, E> is a type similar to Either in Haskell and it allows us to chain multiple operations on correct results or propagate the original error without doing anything. Let's dissect it one-by-one.

    @@ -1182,7 +1182,7 @@ types and either successfully convert them or fail (with a reasonable error). Th method returns Result<T, E>.

    We call and_then on that result, let's have a look at the type signature of and_then, IMO it explains more than enough:

    -
    pub fn and_then<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> Result<U, E>
    +
    pub fn and_then<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> Result<U, E>

    OK… So it takes the result and a function and returns another result with different value and different error. However we can see that the function, which represents an operation on a result, takes just the value, i.e. it doesn't care @@ -1192,7 +1192,7 @@ about any previous error. To make it short:

    We parsed a y index and now we try to convert the x index with try_from again, but on that result we use map rather than and_then, why would that be?

    -
    pub fn map<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> U
    +
    pub fn map<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> U

    Huh… map performs an operation that cannot fail. And finally we use unwrap_or which takes the value from result, or in case of an error returns the default that we define.

    @@ -1221,13 +1221,13 @@ preparations for the AoC. Let's sum up our requirements:

    cannot do anything about it. However running and testing can be simplified!

    Let's introduce and export a new module solution that will take care of all of this. We will start by introducing a trait for each day.

    -
    pub trait Solution<Input, Output: Display> {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input;

    fn part_1(input: &Input) -> Output;
    fn part_2(input: &Input) -> Output;
    }
    +
    pub trait Solution<Input, Output: Display> {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input;

    fn part_1(input: &Input) -> Output;
    fn part_2(input: &Input) -> Output;
    }

    This does a lot of work for us already, we have defined a trait and for each day we will create a structure representing a specific day. That structure will also implement the Solution trait.

    Now we need to get rid of the boilerplate, we can't get rid of the main function, but we can at least move out the functionality.

    -
    fn run(type_of_input: &str) -> Result<()>
    where
    Self: Sized,
    {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = Self::parse_input(format!("{}s/{}.txt", type_of_input, Self::day()));

    info!("Part 1: {}", Self::part_1(&input));
    info!("Part 2: {}", Self::part_2(&input));

    Ok(())
    }

    fn main() -> Result<()>
    where
    Self: Sized,
    {
    Self::run("input")
    }
    +
    fn run(type_of_input: &str) -> Result<()>
    where
    Self: Sized,
    {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = Self::parse_input(format!("{}s/{}.txt", type_of_input, Self::day()));

    info!("Part 1: {}", Self::part_1(&input));
    info!("Part 2: {}", Self::part_2(&input));

    Ok(())
    }

    fn main() -> Result<()>
    where
    Self: Sized,
    {
    Self::run("input")
    }

    This is all part of the Solution trait, which can implement methods while being dependent on what is provided by the implementing types. In this case, we just need to bound the Output type to implement Display that is necessary for the @@ -1236,14 +1236,14 @@ need to bound the Output type to implement Display tha day() method that you can see being used when constructing path to the input file. That method will generate a name of the file, e.g. day01 and we know that we can somehow deduce it from the structure name, given we name it reasonably.

    -
    fn day() -> String {
    let mut day = String::from(type_name::<Self>().split("::").next().unwrap());
    day.make_ascii_lowercase();

    day.to_string()
    }
    +
    fn day() -> String {
    let mut day = String::from(type_name::<Self>().split("::").next().unwrap());
    day.make_ascii_lowercase();

    day.to_string()
    }
    type_name

    This feature is still experimental and considered to be internal, it is not advised to use it any production code.

    And now we can get to the nastiest stuff 😩 We will generate the tests!

    We want to be able to generate tests for sample input in a following way:

    -
    test_sample!(day_01, Day01, 42, 69);
    +
    test_sample!(day_01, Day01, 42, 69);

    There's not much we can do, so we will write a macro to generate the tests for us.

    -
    #[macro_export]
    macro_rules! test_sample {
    ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {
    #[cfg(test)]
    mod $mod_name {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_1(&sample), $part_1);
    }

    #[test]
    fn test_part_2() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_2(&sample), $part_2);
    }
    }
    };
    }
    +
    #[macro_export]
    macro_rules! test_sample {
    ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {
    #[cfg(test)]
    mod $mod_name {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_1(&sample), $part_1);
    }

    #[test]
    fn test_part_2() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_2(&sample), $part_2);
    }
    }
    };
    }

    We have used it in a similar way as macros in C/C++, one of the things that we can use to our advantage is defining “type” of the parameters for the macro. All parameters have their name prefixed with $ sign and you can define various “forms” @@ -1259,7 +1259,7 @@ which literally means an expression.

    Apart from that we need to use #[macro_export] to mark the macro as exported for usage outside of the module. Now our skeleton looks like:

    -
    use aoc_2022::*;

    type Input = String;
    type Output = String;

    struct DayXX;
    impl Solution<Input, Output> for DayXX {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
    file_to_string(pathname)
    }

    fn part_1(input: &Input) -> Output {
    todo!()
    }

    fn part_2(input: &Input) -> Output {
    todo!()
    }
    }

    fn main() -> Result<()> {
    // DayXX::run("sample")
    DayXX::main()
    }

    // test_sample!(day_XX, DayXX, , );
    +
    use aoc_2022::*;

    type Input = String;
    type Output = String;

    struct DayXX;
    impl Solution<Input, Output> for DayXX {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
    file_to_string(pathname)
    }

    fn part_1(input: &Input) -> Output {
    todo!()
    }

    fn part_2(input: &Input) -> Output {
    todo!()
    }
    }

    fn main() -> Result<()> {
    // DayXX::run("sample")
    DayXX::main()
    }

    // test_sample!(day_XX, DayXX, , );

    Solution

    Not much to talk about, it is relatively easy to simulate.

    Day 10: Cathode-Ray Tube

    @@ -1269,7 +1269,7 @@ CPU's accumulator.

    And the issue is caused by different types of Output for the part 1 and part 2.

    Problem is relatively simple and consists of simulating a CPU, I have approached it in a following way:

    -
    fn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {
    instructions
    .iter()
    .fold(State::new(), |state, instruction| {
    state.execute(instruction, &mut out)
    });

    out
    }
    +
    fn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {
    instructions
    .iter()
    .fold(State::new(), |state, instruction| {
    state.execute(instruction, &mut out)
    });

    out
    }

    We just take the instructions, we have some state of the CPU and we execute the instructions one-by-one. Perfect usage of the fold (or reduce as you may know it from other languages).

    @@ -1277,11 +1277,11 @@ it from other languages).

    that problem. And the answer is very simple and functional. Rust allows you to have an enumeration that can bear some other values apart from the type itself.

    tip

    We could've seen something like this with the Result<T, E> type that can be -defined as

    enum Result<T, E> {
    Ok(T),
    Err(E)
    }
    What does that mean though?

    When we have an Ok value, it has the result itself, and when we get an Err +defined as

    enum Result<T, E> {
    Ok(T),
    Err(E)
    }
    What does that mean though?

    When we have an Ok value, it has the result itself, and when we get an Err value, it has the error. This also allows us to handle results in a rather -pretty way:

    match do_something(x) {
    Ok(y) => {
    println!("SUCCESS: {}", y);
    },
    Err(y) => {
    eprintln!("ERROR: {}", y);
    }
    }
    +pretty way:

    match do_something(x) {
    Ok(y) => {
    println!("SUCCESS: {}", y);
    },
    Err(y) => {
    eprintln!("ERROR: {}", y);
    }
    }

    My solution has a following outline:

    -
    fn execute(&self, i: &Instruction, output: &mut Output) -> State {
    // execute the instruction

    // collect results if necessary
    match output {
    Output::Part1(x) => self.execute_part_1(y, x),
    Output::Part2(x) => self.execute_part_2(y, x),
    }

    // return the obtained state
    new_state
    }
    +
    fn execute(&self, i: &Instruction, output: &mut Output) -> State {
    // execute the instruction

    // collect results if necessary
    match output {
    Output::Part1(x) => self.execute_part_1(y, x),
    Output::Part2(x) => self.execute_part_2(y, x),
    }

    // return the obtained state
    new_state
    }

    You might think that it's a perfectly reasonable thing to do. Yes, but notice that the match statement doesn't collect the changes in any way and also we pass output by &mut, so it is shared across each iteration of the fold.

    @@ -1308,7 +1308,7 @@ also rolling down the hill…

    As I have said in the tl;dr, we are looking for the shortest path, but the start and goal differ for the part 1 and 2. So I have decided to refactor my solution to a BFS algorithm that takes necessary parameters via functions:

    -
    fn bfs<F, G>(
    graph: &[Vec<char>], start: &Position, has_edge: F, is_target: G
    ) -> Option<usize>
    where
    F: Fn(&[Vec<char>], &Position, &Position) -> bool,
    G: Fn(&[Vec<char>], &Position) -> bool
    +
    fn bfs<F, G>(
    graph: &[Vec<char>], start: &Position, has_edge: F, is_target: G
    ) -> Option<usize>
    where
    F: Fn(&[Vec<char>], &Position, &Position) -> bool,
    G: Fn(&[Vec<char>], &Position) -> bool

    We pass the initial vertex from the caller and everything else is left to the BFS algorithm, based on the has_edge and is_target functions.

    This was easy! And that is not very usual in Rust once you want to pass around @@ -1325,7 +1325,7 @@ time complexity, because of the priority heap instead of the queue.

    You can implement a lot of traits if you want to. It is imperative to implement ordering on the packets. I had a typo, so I also proceeded to implement a Display trait for debugging purposes:

    -
    impl Display for Packet {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
    Packet::Integer(x) => write!(f, "{x}"),
    Packet::List(lst) => write!(f, "[{}]", lst.iter().map(|p| format!("{p}")).join(",")),
    }
    }
    }
    +
    impl Display for Packet {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
    Packet::Integer(x) => write!(f, "{x}"),
    Packet::List(lst) => write!(f, "[{}]", lst.iter().map(|p| format!("{p}")).join(",")),
    }
    }
    }

    Solution

    A lot of technical details… Parsing is nasty too…

    Day 14: Regolith Reservoir

    @@ -1345,16 +1345,16 @@ leave it be, so I tried to implement the Index and IndexMutunsafe
    part are the 2 methods that are named *unchecked*. Anyways, I will be implementing the Index* traits for now, rather than the SliceIndex.

    It's relatively straightforward…

    -
    impl<I, C> Index<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    +
    impl<I, C> Index<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }

    We can see a lot of similarities to the implementation of index and index_mut functions. In the end, they are 1:1, just wrapped in the trait that provides a syntax sugar for container[idx].

    note

    I have also switched from using the TryFrom to TryInto trait, since it better matches what we are using, the .try_into rather than usize::try_from.

    Also implementing TryFrom automatically provides you with a TryInto trait, -since it is relatively easy to implement. Just compare the following:

    pub trait TryFrom<T>: Sized {
    type Error;

    fn try_from(value: T) -> Result<Self, Self::Error>;
    }

    pub trait TryInto<T>: Sized {
    type Error;

    fn try_into(self) -> Result<T, Self::Error>;
    }
    +since it is relatively easy to implement. Just compare the following:

    pub trait TryFrom<T>: Sized {
    type Error;

    fn try_from(value: T) -> Result<Self, Self::Error>;
    }

    pub trait TryInto<T>: Sized {
    type Error;

    fn try_into(self) -> Result<T, Self::Error>;
    }

    OK, so we have our trait implemented, we should be able to use container[index], right? Yes… but actually no 😦

    -
    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:26:18
    |
    26 | if trees[pos] > tallest {
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:30:28
    |
    30 | max(tallest, trees[pos])
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<isize>`
    --> src/bin/day08.rs:52:28
    |
    52 | let max_height = trees[position];
    | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<isize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<isize>>`
    +
    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:26:18
    |
    26 | if trees[pos] > tallest {
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:30:28
    |
    30 | max(tallest, trees[pos])
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<isize>`
    --> src/bin/day08.rs:52:28
    |
    52 | let max_height = trees[position];
    | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<isize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<isize>>`

    Why? We have it implemented for the slices ([C]), why doesn't it work? Well, the fun part consists of the fact that in other place, where we were using it, we were passing the &[Vec<T>], but this is coming from a helper functions that @@ -1364,9 +1364,9 @@ those. Just for the slices. 🤯 What are we going to do about it?

    so let's implement a macro! The only difference across the implementations are the types of the outer containers. Implementation doesn't differ at all!

    Implementing the macro can be done in a following way:

    -
    macro_rules! generate_indices {
    ($container:ty) => {
    impl<I, C> Index<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    };
    }
    +
    macro_rules! generate_indices {
    ($container:ty) => {
    impl<I, C> Index<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    };
    }

    And now we can simply do

    -
    generate_indices!(VecDeque<C>);
    generate_indices!([C]);
    generate_indices!(Vec<C>);
    // generate_indices!([C; N], const N: usize);
    +
    generate_indices!(VecDeque<C>);
    generate_indices!([C]);
    generate_indices!(Vec<C>);
    // generate_indices!([C; N], const N: usize);

    The last type (I took the inspiration from the implementations of the Index and IndexMut traits) is a bit problematic, because of the const N: usize part, which I haven't managed to be able to parse. And that's how I got rid of the error.

    @@ -1376,11 +1376,11 @@ copy-paste, cause the cost of this “monstrosity” outweighs the benefits of n

    This issue is relatively funny. If you don't use any type aliases, just the raw types, you'll get suggested certain changes by the clippy. For example if you consider the following piece of code

    -
    fn get_sum(nums: &Vec<i32>) -> i32 {
    nums.iter().sum()
    }

    fn main() {
    let nums = vec![1, 2, 3];
    println!("Sum: {}", get_sum(&nums));
    }
    +
    fn get_sum(nums: &Vec<i32>) -> i32 {
    nums.iter().sum()
    }

    fn main() {
    let nums = vec![1, 2, 3];
    println!("Sum: {}", get_sum(&nums));
    }

    and you run clippy on it, you will get

    -
    Checking playground v0.0.1 (/playground)
    warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
    --> src/main.rs:1:18
    |
    1 | fn get_sum(nums: &Vec<i32>) -> i32 {
    | ^^^^^^^^^ help: change this to: `&[i32]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
    = note: `#[warn(clippy::ptr_arg)]` on by default

    warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.61s
    +
    Checking playground v0.0.1 (/playground)
    warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
    --> src/main.rs:1:18
    |
    1 | fn get_sum(nums: &Vec<i32>) -> i32 {
    | ^^^^^^^^^ help: change this to: `&[i32]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
    = note: `#[warn(clippy::ptr_arg)]` on by default

    warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.61s

    However, if you introduce a type alias, such as

    -
    type Numbers = Vec<i32>;
    +
    type Numbers = Vec<i32>;

    Then clippy won't say anything, cause there is literally nothing to suggest. However the outcome is not the same…

    ]]> @@ -1415,10 +1415,10 @@ backpacks and we want to choose the elf that has the most food ;)

    At first I've decided to put asserts into my main, something like

    -
    assert_eq!(part_1(&sample), 24000);
    info!("Part 1: {}", part_1(&input));

    assert_eq!(part_2(&sample), 45000);
    info!("Part 2: {}", part_2(&input));
    +
    assert_eq!(part_1(&sample), 24000);
    info!("Part 1: {}", part_1(&input));

    assert_eq!(part_2(&sample), 45000);
    info!("Part 2: {}", part_2(&input));

    However, once you get further, the sample input may take some time to run itself. So in the end, I have decided to turn them into unit tests:

    -
    #[cfg(test)]
    mod tests {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample = parse_input("samples/day01.txt");
    assert_eq!(part_1(&sample), 24000);
    }

    #[test]
    fn test_part_2() {
    let sample = parse_input("samples/day01.txt");
    assert_eq!(part_2(&sample), 45000);
    }
    }
    +
    #[cfg(test)]
    mod tests {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample = parse_input("samples/day01.txt");
    assert_eq!(part_1(&sample), 24000);
    }

    #[test]
    fn test_part_2() {
    let sample = parse_input("samples/day01.txt");
    assert_eq!(part_2(&sample), 45000);
    }
    }

    And later on I have noticed, it's hard to tell the difference between the days, so I further renamed the mod from generic tests to reflect the days.

    Also after finishing the first day puzzle, I have installed an sccache to @@ -1447,16 +1447,16 @@ to give up. Let's dive into it \o/

    Fun fact

    Fighting the compiler took me 30 minutes.

    We need to find a common item among 2 collections, that's an easy task, right? We can construct 2 sets and find an intersection:

    -
    let top: HashSet<i32> = [1, 2, 3].iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5].iter().collect();
    +
    let top: HashSet<i32> = [1, 2, 3].iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5].iter().collect();

    Now, the first issue that we encounter is caused by the fact that we are using a slice (the […]), iterator of that returns references to the numbers. And we get immediately yelled at by the compiler, because the numbers are discarded after running the .collect. To fix this, we can use .into_iter:

    -
    let top: HashSet<i32> = [1, 2, 3].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5].into_iter().collect();
    +
    let top: HashSet<i32> = [1, 2, 3].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5].into_iter().collect();

    This way the numbers will get copied instead of referenced. OK, let's find the intersection of those 2 collections:

    -
    println!("Common elements: {:?}", top.intersection(&bottom));
    -
    Common elements: [3]
    +
    println!("Common elements: {:?}", top.intersection(&bottom));
    +
    Common elements: [3]
    caution

    Notice that we need to do &bottom. It explicitly specifies that .intersection borrows the bottom, i.e. takes an immutable reference to it.

    That's what we want, right? Looks like it! \o/

    @@ -1464,16 +1464,16 @@ intersection of those 2 collections:

    that should be fairly easy, we have an intersection and we want to find intersection over all of them.

    Let's have a look at the type of the .intersection

    -
    pub fn intersection<'a>(
        &'a self,
        other: &'a HashSet<T, S>
    ) -> Intersection<'a, T, S>
    +
    pub fn intersection<'a>(
        &'a self,
        other: &'a HashSet<T, S>
    ) -> Intersection<'a, T, S>

    OK… Huh… But we have an example there!

    -
    let intersection: HashSet<_> = a.intersection(&b).collect();
    +
    let intersection: HashSet<_> = a.intersection(&b).collect();

    Cool, that's all we need.

    -
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).collect();
    println!("Intersection: {:?}", intersection);
    -
    Intersection: {3, 4}
    +
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).collect();
    println!("Intersection: {:?}", intersection);
    +
    Intersection: {3, 4}

    Cool, so let's do the intersection with the top_2:

    -
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).collect();
    let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
    println!("Intersection: {:?}", intersection);
    +
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).collect();
    let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
    println!("Intersection: {:?}", intersection);

    And we get yelled at by the compiler:

    -
    error[E0308]: mismatched types
    --> src/main.rs:10:58
    |
    10 | let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
    | ------------ ^^^^^^ expected `&i32`, found `i32`
    | |
    | arguments to this function are incorrect
    |
    = note: expected reference `&HashSet<&i32>`
    found reference `&HashSet<i32>`
    +
    error[E0308]: mismatched types
    --> src/main.rs:10:58
    |
    10 | let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
    | ------------ ^^^^^^ expected `&i32`, found `i32`
    | |
    | arguments to this function are incorrect
    |
    = note: expected reference `&HashSet<&i32>`
    found reference `&HashSet<i32>`

    /o\ What the hell is going on here? Well, the funny thing is, that this operation doesn't return the elements themselves, but the references to them and when we pass the third set, it has just the values themselves, without any references.

    @@ -1483,8 +1483,8 @@ a “tax” for having a borrow checker drilling your ass having your making sure you're not doing something naughty that may cause an undefined behavior.

    To resolve this we need to get an iterator that clones the elements:

    -
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).cloned().collect();
    let intersection: HashSet<_> = intersection.intersection(&top_2).cloned().collect();
    let intersection: HashSet<_> = intersection.intersection(&bottom_2).cloned().collect();
    println!("Intersection: {:?}", intersection);
    -
    Intersection: {4}
    +
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).cloned().collect();
    let intersection: HashSet<_> = intersection.intersection(&top_2).cloned().collect();
    let intersection: HashSet<_> = intersection.intersection(&bottom_2).cloned().collect();
    println!("Intersection: {:?}", intersection);
    +
    Intersection: {4}

    Solution

    The approach is pretty simple, if you omit the 1on1 with the compiler. You just have some fun with the set operations :)

    @@ -1498,7 +1498,7 @@ Find how many overlap and can take the day off.

    Day 5: Supply Stacks

    tl;dr

    Let's play with stacks of crates.

    Very easy problem with very annoying input. You can judge yourself:

    -
        [D]
    [N] [C]
    [Z] [M] [P]
    1 2 3

    move 1 from 2 to 1
    move 3 from 1 to 3
    move 2 from 2 to 1
    move 1 from 1 to 2
    +
        [D]
    [N] [C]
    [Z] [M] [P]
    1 2 3

    move 1 from 2 to 1
    move 3 from 1 to 3
    move 2 from 2 to 1
    move 1 from 1 to 2

    Good luck transforming that into something reasonable :)

    Fun fact

    Took me 40 minutes to parse this reasonably, including fighting the compiler.

    Solution

    @@ -1506,7 +1506,7 @@ Find how many overlap and can take the day off.

    the work. Later on I have decided to explore the std and interface of the std::vec::Vec and found split_off which takes an index and splits (duh) the vector:

    -
    let mut vec = vec![1, 2, 3];
    let vec2 = vec.split_off(1);
    assert_eq!(vec, [1]);
    assert_eq!(vec2, [2, 3]);
    +
    let mut vec = vec![1, 2, 3];
    let vec2 = vec.split_off(1);
    assert_eq!(vec, [1]);
    assert_eq!(vec2, [2, 3]);

    This helped me simplify my solution a lot and also get rid of some edge cases.

    Day 6: Tuning Trouble

    tl;dr

    Finding start of the message in a very weird protocol. Start of the message is @@ -1531,7 +1531,7 @@ directories that take a lot of space and should be deleted.

    Solution

    We need to “build” a file system from the input that is given in a following form:

    -
    $ cd /
    $ ls
    dir a
    14848514 b.txt
    8504156 c.dat
    dir d
    $ cd a
    $ ls
    dir e
    29116 f
    2557 g
    62596 h.lst
    $ cd e
    $ ls
    584 i
    $ cd ..
    $ cd ..
    $ cd d
    $ ls
    4060174 j
    8033020 d.log
    5626152 d.ext
    7214296 k
    +
    $ cd /
    $ ls
    dir a
    14848514 b.txt
    8504156 c.dat
    dir d
    $ cd a
    $ ls
    dir e
    29116 f
    2557 g
    62596 h.lst
    $ cd e
    $ ls
    584 i
    $ cd ..
    $ cd ..
    $ cd d
    $ ls
    4060174 j
    8033020 d.log
    5626152 d.ext
    7214296 k

    There are few ways in which you can achieve this and also you can assume some preconditions, but why would we do that, right? :)

    You can “slap” this in either HashMap or BTreeMap and call it a day. @@ -1551,7 +1551,7 @@ references are present) are checked dynamically.

    So in the end, if you wan to have Rc<RefCell<T>>.

    So, how are we going to represent the file system then? We will use an enumeration, hehe, which is an algebraic data type that can store some stuff in itself 😩

    -
    type FileHandle = Rc<RefCell<AocFile>>;

    #[derive(Debug)]
    enum AocFile {
    File(usize),
    Directory(BTreeMap<String, FileHandle>),
    }
    +
    type FileHandle = Rc<RefCell<AocFile>>;

    #[derive(Debug)]
    enum AocFile {
    File(usize),
    Directory(BTreeMap<String, FileHandle>),
    }

    Let's go over it! FileHandle represents dynamically allocated AocFile, not much to discuss. What does the #[derive(Debug)] do though? It lets us to print out the value of that enumeration, it's derived, so it's not as good as if we had @@ -1653,15 +1653,15 @@ problems in it. However the toolkit is questionable :/

    with rust-analyzer. Because of my choice of libraries, we will also introduce a .envrc file that can be used by direnv, which allows you to set specific environment variables when you enter a directory. In our case, we will use

    -
    # to show nice backtrace when using the color-eyre
    export RUST_BACKTRACE=1

    # to catch logs generated by tracing
    export RUST_LOG=trace
    +
    # to show nice backtrace when using the color-eyre
    export RUST_BACKTRACE=1

    # to catch logs generated by tracing
    export RUST_LOG=trace

    And for the one of the most obnoxious things ever, we will use a script to download the inputs instead of “clicking, opening and copying to a file1. There is no need to be fancy, so we will adjust Python script by Martin2.

    -
    #!/usr/bin/env python3

    import datetime
    import yaml
    import requests
    import sys


    def load_config():
    with open("env.yaml", "r") as f:
    js = yaml.load(f, Loader=yaml.Loader)
    return js["session"], js["year"]


    def get_input(session, year, day):
    return requests.get(
    f"https://adventofcode.com/{year}/day/{day}/input",
    cookies={"session": session},
    headers={
    "User-Agent": "{repo} by {mail}".format(
    repo="gitlab.com/mfocko/advent-of-code-2022",
    mail="me@mfocko.xyz",
    )
    },
    ).content.decode("utf-8")


    def main():
    day = datetime.datetime.now().day
    if len(sys.argv) == 2:
    day = sys.argv[1]

    session, year = load_config()
    problem_input = get_input(session, year, day)

    with open(f"./inputs/day{day:>02}.txt", "w") as f:
    f.write(problem_input)


    if __name__ == "__main__":
    main()
    +
    #!/usr/bin/env python3

    import datetime
    import yaml
    import requests
    import sys


    def load_config():
    with open("env.yaml", "r") as f:
    js = yaml.load(f, Loader=yaml.Loader)
    return js["session"], js["year"]


    def get_input(session, year, day):
    return requests.get(
    f"https://adventofcode.com/{year}/day/{day}/input",
    cookies={"session": session},
    headers={
    "User-Agent": "{repo} by {mail}".format(
    repo="gitlab.com/mfocko/advent-of-code-2022",
    mail="me@mfocko.xyz",
    )
    },
    ).content.decode("utf-8")


    def main():
    day = datetime.datetime.now().day
    if len(sys.argv) == 2:
    day = sys.argv[1]

    session, year = load_config()
    problem_input = get_input(session, year, day)

    with open(f"./inputs/day{day:>02}.txt", "w") as f:
    f.write(problem_input)


    if __name__ == "__main__":
    main()

    If the script is called without any arguments, it will deduce the day from the system, so we do not need to change the day every morning. It also requires a configuration file:

    -
    # env.yaml
    session: ‹your session cookie›
    year: 2022
    +
    # env.yaml
    session: ‹your session cookie›
    year: 2022

    Libraries

    Looking at the list of the libraries, I have chosen “a lot” of them. Let's walk through each of them.

    @@ -1690,7 +1690,7 @@ also we can follow KISS. I have 2 modules that my “library” exports parsing and one for 2D vector (that gets used quite often during Advent of Code).

    Key part is, of course, processing the input and my library exports following functions that get used a lot:

    -
    /// Reads file to the string.
    pub fn file_to_string<P: AsRef<Path>>(pathname: P) -> String;

    /// Reads file and returns it as a vector of characters.
    pub fn file_to_chars<P: AsRef<Path>>(pathname: P) -> Vec<char>;

    /// Reads file and returns a vector of parsed structures. Expects each structure
    /// on its own line in the file. And `T` needs to implement `FromStr` trait.
    pub fn file_to_structs<P: AsRef<Path>, T: FromStr>(pathname: P) -> Vec<T>
    where
    <T as FromStr>::Err: Debug;

    /// Converts iterator over strings to a vector of parsed structures. `T` needs
    /// to implement `FromStr` trait and its error must derive `Debug` trait.
    pub fn strings_to_structs<T: FromStr, U>(
    iter: impl Iterator<Item = U>
    ) -> Vec<T>
    where
    <T as std::str::FromStr>::Err: std::fmt::Debug,
    U: Deref<Target = str>;

    /// Reads file and returns it as a vector of its lines.
    pub fn file_to_lines<P: AsRef<Path>>(pathname: P) -> Vec<String>;
    +
    /// Reads file to the string.
    pub fn file_to_string<P: AsRef<Path>>(pathname: P) -> String;

    /// Reads file and returns it as a vector of characters.
    pub fn file_to_chars<P: AsRef<Path>>(pathname: P) -> Vec<char>;

    /// Reads file and returns a vector of parsed structures. Expects each structure
    /// on its own line in the file. And `T` needs to implement `FromStr` trait.
    pub fn file_to_structs<P: AsRef<Path>, T: FromStr>(pathname: P) -> Vec<T>
    where
    <T as FromStr>::Err: Debug;

    /// Converts iterator over strings to a vector of parsed structures. `T` needs
    /// to implement `FromStr` trait and its error must derive `Debug` trait.
    pub fn strings_to_structs<T: FromStr, U>(
    iter: impl Iterator<Item = U>
    ) -> Vec<T>
    where
    <T as std::str::FromStr>::Err: std::fmt::Debug,
    U: Deref<Target = str>;

    /// Reads file and returns it as a vector of its lines.
    pub fn file_to_lines<P: AsRef<Path>>(pathname: P) -> Vec<String>;

    As for the vector, I went with a rather simple implementation that allows only addition of the vectors for now and accessing the elements via functions x() and y(). Also the vector is generic, so we can use it with any numeric type we @@ -1699,36 +1699,36 @@ need.

    We can also prepare a template to quickly bootstrap each of the days. We know that each puzzle has 2 parts, which means that we can start with 2 functions that will solve them.

    -
    fn part1(input: &Input) -> Output {
    todo!()
    }

    fn part2(input: &Input) -> Output {
    todo!()
    }
    +
    fn part1(input: &Input) -> Output {
    todo!()
    }

    fn part2(input: &Input) -> Output {
    todo!()
    }

    Both functions take reference to the input and return some output (in majority of puzzles, it is the same type). todo!() can be used as a nice placeholder, it also causes a panic when reached and we could also provide some string with an explanation, e.g. todo!("part 1"). We have not given functions a specific type and to avoid as much copy-paste as possible, we will introduce type aliases.

    -
    type Input = String;
    type Output = i32;
    +
    type Input = String;
    type Output = i32;
    tip

    This allows us to quickly adjust the types only in one place without the need to do regex-replace or replace them manually.

    For each day we get a personalized input that is provided as a text file. Almost all the time, we would like to get some structured type out of that input, and therefore it makes sense to introduce a new function that will provide the parsing of the input.

    -
    fn parse_input(path: &str) -> Input {
    todo!()
    }
    +
    fn parse_input(path: &str) -> Input {
    todo!()
    }

    This “parser” will take a path to the file, just in case we would like to run the sample instead of input.

    OK, so now we can write a main function that will take all of the pieces and run them.

    -
    fn main() {
    let input = parse_input("inputs/dayXX.txt");

    println!("Part 1: {}", part_1(&input));
    println!("Part 2: {}", part_2(&input));
    }
    +
    fn main() {
    let input = parse_input("inputs/dayXX.txt");

    println!("Part 1: {}", part_1(&input));
    println!("Part 2: {}", part_2(&input));
    }

    This would definitely do :) But we have installed a few libraries and we want to use them. In this part we are going to utilize tracing (for tracing, duh…) and color-eyre (for better error reporting, e.g. from parsing).

    -
    fn main() -> Result<()> {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = parse_input("inputs/dayXX.txt");

    info!("Part 1: {}", part_1(&input));
    info!("Part 2: {}", part_2(&input));

    Ok(())
    }
    +
    fn main() -> Result<()> {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = parse_input("inputs/dayXX.txt");

    info!("Part 1: {}", part_1(&input));
    info!("Part 2: {}", part_2(&input));

    Ok(())
    }

    The first statement will set up tracing and configure it to print out the logs to terminal, based on the environment variable. We also change the formatting a bit, since we do not need all the fancy features of the logger. Pure initialization would get us logs like this:

    -
    2022-12-11T19:53:19.975343Z  INFO day01: Part 1: 0
    +
    2022-12-11T19:53:19.975343Z  INFO day01: Part 1: 0

    However after running that command, we will get the following:

    -
     INFO src/bin/day01.rs:35: Part 1: 0
    +
     INFO src/bin/day01.rs:35: Part 1: 0

    And the color_eyre::install()? is quite straightforward. We just initialize the error reporting by color eyre.

    caution

    Notice that we had to add Ok(()) to the end of the function and adjust the @@ -1736,7 +1736,7 @@ return type of the main to Result<()>. It is cau can be installed only once and therefore it can fail, that is how we got the ? at the end of the ::install which unwraps the »result« of the installation.

    Overall we will get to a template like this:

    -
    use aoc_2022::*;

    use color_eyre::eyre::Result;
    use tracing::info;
    use tracing_subscriber::EnvFilter;

    type Input = String;
    type Output = i32;

    fn parse_input(path: &str) -> Input {
    todo!()
    }

    fn part1(input: &Input) -> Output {
    todo!()
    }

    fn part2(input: &Input) -> Output {
    todo!()
    }

    fn main() -> Result<()> {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = parse_input("inputs/dayXX.txt");

    info!("Part 1: {}", part_1(&input));
    info!("Part 2: {}", part_2(&input));

    Ok(())
    }
    +
    use aoc_2022::*;

    use color_eyre::eyre::Result;
    use tracing::info;
    use tracing_subscriber::EnvFilter;

    type Input = String;
    type Output = i32;

    fn parse_input(path: &str) -> Input {
    todo!()
    }

    fn part1(input: &Input) -> Output {
    todo!()
    }

    fn part2(input: &Input) -> Output {
    todo!()
    }

    fn main() -> Result<()> {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = parse_input("inputs/dayXX.txt");

    info!("Part 1: {}", part_1(&input));
    info!("Part 2: {}", part_2(&input));

    Ok(())
    }

    Footnotes

    1. diff --git a/blog/feed.json b/blog/feed.json index 0e51b17..9fa6eb4 100644 --- a/blog/feed.json +++ b/blog/feed.json @@ -6,7 +6,7 @@ "items": [ { "id": "https://blog.mfocko.xyz/blog/2024/01/28/rust-opinion", - "content_html": "

      Rust has become a rather popular language these days. I've managed to get my\nhands dirty with it during Advent of Code ‘22 and partially ‘23. I've also\nused it for few rounds of Codeforces and I have to try very hard to maintain\nsome variety of languages for LeetCode challenges along with the Rust. I'll\ndisclaim up front that I won't be only positive, since this post is a result of\nmultiple discussions about Rust and I stand behind\n“All that glitters is not gold”, so if you can't stand your favorite language\nbeing criticized in any way, don't even proceed. 😉

      \n

      Memory safety

      \n

      I'll start by kicking the biggest benefit of the language, the memory safety.\nLet's be honest here, majority of the checks rely on the static analysis, cause\nyou can't do anything else during the compile-time, right? Therefore we can\nbasically say that we are relying on the compiler to “solve” all of our issues.

      \n
      warning

      I'm not doubting the fact that compiler can prevent a lot of the memory\nerrors, I'm just saying it's not realistic to cover everything.

      \n

      Compiler

      \n

      I guess we can safely1 agree on the fact that we 100% rely on the compiler to\nhave our back. Is the compiler bug-free? I doubt it. This is not meant in an\noffensive way to the Rust compiler developers, but we need to be realistic here.\nIt's a compiler, even older and larger projects like gcc or llvm can't avoid\nbugs to appear.

      \n

      When I was trying out Rust for some of the LeetCode challenges I've stumbled\nupon the following warning:\n\"Example

      \n

      The issue here comes from the fact that we have 2 simultaneous references to the\nsame memory (one is mutable and one immutable). If you cannot think of any way\nthis can break, I'll give you a rather simple example from C++ where this could\ncause an issue.

      Imagine a function that has some complex object and also calls a coroutine which\nutilizes read-only reference to that object. When the coroutine suspends, the\ncaller can modify the object. This can break the integrity of data read by the\ncoroutine.

        \n
      • Yes, this can cause a memory error.
      • \n
      • Yes, this hasn't been handled until someone noticed it.
      • \n

      Fixing this bug is not backwards compatible, cause you're covering a case that\nhasn't been covered before.

      \n

      Enforcing the safety

      \n

      One of the ways Rust enforces the safety is by restricting what you can do, like\nthe example above. Aforementioned issue can happen, but doesn't have to.\nRule of the thumb in the Rust compiler is to “block” anything that can be an\nissue, static analysis can't do much more, it cannot decide whether it's safe to\ndo it or not.

      \n

      Satisfying the Rust compiler is sometimes a brutal pain in the ass, because you\ncannot do things like you're used to, you need to work around them somehow.

      \n
      tip

      Key difference between Rust and C or C++ lies in the fact that Rust chooses to\nban all “potentially offensive” actions, C and C++ relies on you to be\nsure it's safe to do.

      \"C++

      \n

      Consequences

      \n

      Where are we heading with this approach of “if it compiles, it runs” though?\nIn this aspect I have a rather similar opinion as with regards to the ChatGPT\nand its derivatives.

      \n

      If you teach people to 100% depend on the compiler, they will do it, cause it's\neasy. All you need to do is make the compiler shut up2. Giving up the\nintellectual masturbation about the memory safety will make you lose your edge\nover the time. When we get to the point of everyone being in the mindset\nmentioned above, who's going to maintain the compiler? This is the place where\nyou need to think about the memory safety and furthermore in a much more\ngeneral way than in your own projects, because it is the thing that everyone\nblindly believes in in the end.

      \n

      I'm not saying that everyone should give up Rust and think about their memory\nmanagement and potential memory issues. I'm just saying that going the easy way\nwill make people dull and they should think about it anyways, that's how the\nissue above has been discovered. If everyone walked past and didn't think about\nit, no one would discover this issue till it bit them hard.

      \n
      Standard library

      Even the standard library is littered with unsafe blocks that are prefixed\nwith comments in style:

      // SAFETY: …

      The fact that the casual Rust dev doesn't have to think much about safety,\ncause the compiler has their back, doesn't mean that the Rust compiler dev\ndoesn't either.

      I gotta admit that I adopted this concept in other languages (even in Python),\ncause you can encounter situations where it doesn't have to be clear why you\ncan do what you're doing.

      \n

      Development & design

      \n

      Development of Rust is… very fast. One positive is that they're trying to be as\nbackward compatible as possible at least by verifying against all the published\ncrates in the process. Of course, you cannot be backward compatible about fixing\nthe bugs that have been found, but such is life.

      \n

      Fast development cycle

      \n

      One of the negatives of the fast development cycle is the fact that they're\nusing the latest features already in the next release of the Rust. Yes, it is\nsomething that you can use for verifying and testing your own changes, but at\nthe same time it places a requirement of the latest release to compile the next\none.

      \n
      tip

      If you check gcc for example, they have a requirement of minimal version of\ncompiler that you need for the build. Though gcc's requirement is not so needy\nas the Rust one.

      \n

      One of the other negatives is the introduction of bugs. If you're pushing\nchanges, somewhat mindlessly, at such a fast pace, it is inevitable to introduce\na bunch bugs in the process. Checking the GitHub issue tracker with

      \n
      is:issue is:open label:C-bug label:T-compiler
      \n

      yields 2,224 open issues at the time of writing this post.

      \n

      RFCs

      \n

      You can find a lot of RFCs for the Rust. Some of them are more questionable\nthan the others. Fun thing is that a lot of them make it to the nightly builds,\nso they can be tested and polished off. Even the questionable ones… I'll leave\nfew examples for a better understanding.

      \n

      One of such features is the do yeet expression:

      \n
      #![feature(yeet_expr)]

      fn foo() -> Result<String, i32> {
      do yeet 4;
      }
      assert_eq!(foo(), Err(4));

      fn bar() -> Option<String> {
      do yeet;
      }
      assert_eq!(bar(), None);
      \n

      It allows you to “yeet” the errors out of the functions that return Result or\nOption.

      \n

      One of the more recent ones is\nthe ability to include Cargo manifests into the sources, so you can do something\nlike:

      \n
      #!/usr/bin/env cargo
      ---
      [dependencies]
      clap = { version = \"4.2\", features = [\"derive\"] }
      ---

      use clap::Parser;

      #[derive(Parser, Debug)]
      #[clap(version)]
      struct Args {
      #[clap(short, long, help = \"Path to config\")]
      config: Option<std::path::PathBuf>,
      }

      fn main() {
      let args = Args::parse();
      println!(\"{:?}\", args);
      }
      \n

      I would say you can get almost anything into the language…

      \n

      Community and hype train

      \n

      Rust community is a rather unique thing. A lot of people will hate me for this,\nbut I can't help, but to compare them to militant vegans. I'll go through some\nof the things related to it, so I can support my opinion at least.

      \n

      Rust is the best language. It is not. There is no best language, each has its\nown positives and negatives, you need to choose the language that's the most\nsuitable for your use case. There are areas where Rust excels, though I have\nto admit it's very close to being a universal hammer regardless of how suitable\nit is. There is a very steep learning curve to it, beginnings in Rust are very\npainful.

      \n

      Rewrite everything in Rust. Just no. There are multiple feedbacks on doing\nrewrites, it is very common to fix N bugs with a rewrite while introducing\nN + 1 other bugs in the process. It doesn't solve anything unless there are\nsome strong reasons to go with it. Majority of such suggested rewrites don't\nhave those reasons though.

      \n

      Language ‹x› is bad, though in Rust… Cherry-picking one specific pain point of\none language and reflecting how it is better in other language can go both ways.\nFor example it is rather easy to pick the limitations imposed by Rust compiler\nand show how it's possible in other languages 🤷‍♂️

      \n

      I don't mind any of those opinions, you're free to have them, as long as you\ndon't rub them in my face which is not the usual case… This experience makes it\njust worse for me, part of this post may be also influenced by this fact.

      \n

      Rust in Linux

      \n
      caution

      As someone who has seen the way Linux kernel is built in the RHEL ecosystem, how\ncomplex the whole thing is and how much resources you need to proceed, I have\nvery strong opinions on this topic.

      \n

      It took years of work to even “incorporate” Rust into the Linux codebase, just\nto get the “Hello World!”. I don't have anything against the idea of writing\ndrivers in the Rust, I bet it can catch a lot of common mistakes, but still\nintroducing Rust to the kernel is another step to enlarge the monster.

      \n

      I have to admit though that the Apple GPU driver for Linux written in Rust is\nquite impressive. Apart from that there are not so many benefits, yet…

      \n

      Packaging

      \n

      I'll divide the packaging into the packaging of the language itself and the\nprograms written in Rust.

      \n

      Let's start with the cargo itself though. Package managers of the languages\nusually get a lot of hate (you can take npm or pip as examples3). If\nyou've ever tried out Rust, I bet you already know where I'm going with this.\nYes, I mean the compilation times, or even Cargo downloading whole index of\ncrates just so you can update that one dependency (and 3 millions of indirect\ndeps). When I was doing AoC ‘22 in Rust, I've set up sccache right away on the\nfirst day.

      \n

      Let's move to the packaging of the Rust itself, it's tedious. Rust has a very\nfast development cycle and doesn't even try to make the builds backward\ncompatible. If there is a new release of Rust, there is a very high chance that\nyou cannot build that release with anything other than the latest Rust\nrelease. If you have ever touched the packaging, you know that this is something\nthat can cause a lot of problems, cause you need the second-to-latest version to\ncompile the latest version, don't forget that this applies inductively… People\nrunning Gentoo could tell you a lot about this.

      \n
      info

      Compiling the compilers takes usually more time than compiling the kernel\nitself…

      \n

      I cannot speak about packaging of Rust programs in other than RHEL-based\ndistros, though I can speak about RHEL ecosystem. Fedora packaging guidelines\nspecify that you need to build each and every dependency of the program\nseparately. I wanted to try out AlmaLinux and install Alacritty there and I\nfailed miserably. The solution that worked, consisted of ignoring the packaging\nguidelines, running cargo build and consuming the binaries afterwards.\nDependencies of the Rust programs are of a similar nature as JS dependencies.

      \n
      \n

      I'm tipping my fedora1 in the general direction of the maintainers of Rust\npackages in RHEL ecosystem. I wouldn't be able to do this without losing my\nsanity.

      \n
      \n

      Likes

      \n

      If you've come all the way here and you're a Rustacean, I believe I've managed\nto get your blood boiling, so it's time to finish this off by stuff I like about\nRust. I doubt I will be able to cover everything, but I can try at least. You\nhave to admit it's much easier to remember the bad stuff as opposed to the good.\n😉

      \n

      Workflow and toolchain

      \n

      I prefered using Rust for the Advent of Code and Codeforces as it provides\na rather easy way to test the solutions before running them with the challenge\ninput (or test runner). I can give an example from the Advent of Code:

      \n
      use aoc_2023::*;

      type Output1 = i32;
      type Output2 = Output1;

      struct DayXX {}
      impl Solution<Output1, Output2> for DayXX {
      fn new<P: AsRef<Path>>(pathname: P) -> Self {
      let lines: Vec<String> = file_to_lines(pathname);

      todo!()
      }

      fn part_1(&mut self) -> Output1 {
      todo!()
      }

      fn part_2(&mut self) -> Output2 {
      todo!()
      }
      }

      fn main() -> Result<()> {
      DayXX::main()
      }

      test_sample!(day_XX, DayXX, 42, 69);
      \n

      This was the skeleton I've used and the macro at the end is my own creation that\nexpands to:

      \n
      #[cfg(test)]
      mod day_XX {
      use super::*;

      #[test]
      fn part_1() {
      let path = DayXX::get_sample(1);
      let mut day = DayXX::new(path);
      assert_eq!(day.part_1(), 42);
      }

      #[test]
      fn part_2() {
      let path = DayXX::get_sample(2);
      let mut day = DayXX::new(path);
      assert_eq!(day.part_2(), 69);
      }
      }
      \n

      When you're solving the problem, all you need to do is switch between\ncargo test and cargo run to check the answer to either sample or the\nchallenge input itself.

      \n

      Introduce bacon and it gets even better. Bacon is a CLI tool that wraps around\nthe cargo and allows you to check, run, lint or run tests on each file save.\nIt's a very pleasant thing for a so-called compiler-assisted development.

      \n

      Speaking of linting from within the bacon, you cannot leave out the clippy.\nNot only it can whip your ass because of errors, but it can also produce a lot\nof helpful suggestions, for example passing slices by borrow instead of\nborrowing the Vec itself when you don't need it.

      \n

      Standard library

      \n

      There's a lot included in the standard library. It almost feels like you\nhave all you need4. I like placeholders (like todo!(), unreachable!(),\nunimplemented!()) to the extent of\nimplementing them as exceptions in C++.

      \n

      You can find almost anything. Though you can also hit some very weird issues\nwith some of the nuances of the type system.

      \n

      unsafe

      \n

      This might be something that people like to avoid as much as possible. However I\nthink that forming a habit of commenting posibly unsafe operations in any\nlanguage is a good habit, as I've mentioned above. You should be able to argue\nwhy you can do something safely, even if the compiler is not kicking your ass\nbecause of it.

      \n

      Excerpt of such comment from work:

      \n
      # SAFETY: Taking first package instead of specific package should be
      # safe, since we have put a requirement on »one« ‹upstream_project_url›
      # per Packit config, i.e. even if we're dealing with a monorepo, there
      # is only »one« upstream. If there is one upstream, there is only one
      # set of GPG keys that can be allowed.
      return self.downstream_config.packages[
      self.downstream_config._first_package
      ].allowed_gpg_keys
      \n

      Traits

      \n

      One of the other things I like are the traits. They are more restrictive than\ntemplates or concepts in C++, but they're doing their job pretty good. If you\nare building library and require multiple traits to be satisfied it means a lot\nof copy-paste, but that's soon to be fixed by the trait aliases.

      \n
      Comparing to other languages

      On Wikipedia I've seen trait being defined as a more restrictive type class as\nyou may know it from the Haskell for example. C++ isn't behind either with its\nconstraints and concepts. I would say that we can order them in the following\norder based on the complexity they can express:

      Rust's trait < Haskell's type class < C++'s concept
      \n

      You can also hit some issues, like me when trying to support conversions between\nunderlying numeric types of a 2D vectors or support for using an operator from\nboth sides (I couldn't get c * u to work in the same way as u * c because\nthe first one requires you to implement the trait of a built-in type).

      \n
      Implementation

      Implementing traits lies in

      impl SomeTrait for SomeStruct {
      // implementation goes here
      }

      One of the things I would love to see is being able to define the helper\nfunctions within the same block. As of now, the only things allowed are the ones\nthat are required by the trait, which in the end results in a randomly lying\nfunctions around (or in a implementation of the structure itself). I don't like\nthis mess at all…

      \n

      Influence of functional paradigm

      \n

      You can see a big influence of the functional paradigm. Not only in iterators,\nbut also in the other parts of the language. For example I prefer Option<T> or\nResult<T, E> to nulls and exceptions. Pattern matching together with\ncompiler both enforces handling of the errors and rather user-friendly way of\ndoing it.

      \n

      Not to mention .and_then() and such. However spending most of the time with\nthe AoC you get pretty annoyed of the repetitive .unwrap() during parsing,\nsince you are guaranteed correct input.

      \n

      Macros

      \n

      Macros are a very strong pro of the Rust. And no, we're not going to talk about\nthe procedural macros…

      \n

      As I've shown above I've managed to “tame” a lot of copy-paste in the tests for\nthe AoC by utilizing a macro that generated a very basic template for the tests.

      \n

      As I have mentioned the traits above, I cannot forget to give props to derive\nmacro that allows you to “deduce” the default implementation. It is very helpful\nfor a tedious tasks like implementing Debug (for printing out the structures)\nor comparisons, though with the comparisons you need to be careful about the\ndefault implementation, it has already bitten me once or twice.

      \n

      Summary

      \n

      Overall there are many things about the Rust I like and would love to see them\nimplemented in other languages. However there are also many things I don't like.\nNothing is exclusively black and white.

      \n

      Footnotes

      \n
        \n
      1. \n

        pun intended 2

        \n
      2. \n
      3. \n

        It's not that easy with the Rust compiler, but OK…

        \n
      4. \n
      5. \n

        not to even mention multiple different packaging standards Python has, which\nis borderline https://xkcd.com/927/

        \n
      6. \n
      7. \n

        unlike Python where there's whole universe in the language itself, yet there\nare essential things not present…

        \n
      8. \n
      \n
      ", + "content_html": "

      Rust has become a rather popular language these days. I've managed to get my\nhands dirty with it during Advent of Code ‘22 and partially ‘23. I've also\nused it for few rounds of Codeforces and I have to try very hard to maintain\nsome variety of languages for LeetCode challenges along with the Rust. I'll\ndisclaim up front that I won't be only positive, since this post is a result of\nmultiple discussions about Rust and I stand behind\n“All that glitters is not gold”, so if you can't stand your favorite language\nbeing criticized in any way, don't even proceed. 😉

      \n

      Memory safety

      \n

      I'll start by kicking the biggest benefit of the language, the memory safety.\nLet's be honest here, majority of the checks rely on the static analysis, cause\nyou can't do anything else during the compile-time, right? Therefore we can\nbasically say that we are relying on the compiler to “solve” all of our issues.

      \n
      warning

      I'm not doubting the fact that compiler can prevent a lot of the memory\nerrors, I'm just saying it's not realistic to cover everything.

      \n

      Compiler

      \n

      I guess we can safely1 agree on the fact that we 100% rely on the compiler to\nhave our back. Is the compiler bug-free? I doubt it. This is not meant in an\noffensive way to the Rust compiler developers, but we need to be realistic here.\nIt's a compiler, even older and larger projects like gcc or llvm can't avoid\nbugs to appear.

      \n

      When I was trying out Rust for some of the LeetCode challenges I've stumbled\nupon the following warning:\n\"Example

      \n

      The issue here comes from the fact that we have 2 simultaneous references to the\nsame memory (one is mutable and one immutable). If you cannot think of any way\nthis can break, I'll give you a rather simple example from C++ where this could\ncause an issue.

      Imagine a function that has some complex object and also calls a coroutine which\nutilizes read-only reference to that object. When the coroutine suspends, the\ncaller can modify the object. This can break the integrity of data read by the\ncoroutine.

        \n
      • Yes, this can cause a memory error.
      • \n
      • Yes, this hasn't been handled until someone noticed it.
      • \n

      Fixing this bug is not backwards compatible, cause you're covering a case that\nhasn't been covered before.

      \n

      Enforcing the safety

      \n

      One of the ways Rust enforces the safety is by restricting what you can do, like\nthe example above. Aforementioned issue can happen, but doesn't have to.\nRule of the thumb in the Rust compiler is to “block” anything that can be an\nissue, static analysis can't do much more, it cannot decide whether it's safe to\ndo it or not.

      \n

      Satisfying the Rust compiler is sometimes a brutal pain in the ass, because you\ncannot do things like you're used to, you need to work around them somehow.

      \n
      tip

      Key difference between Rust and C or C++ lies in the fact that Rust chooses to\nban all “potentially offensive” actions, C and C++ relies on you to be\nsure it's safe to do.

      \"C++

      \n

      Consequences

      \n

      Where are we heading with this approach of “if it compiles, it runs” though?\nIn this aspect I have a rather similar opinion as with regards to the ChatGPT\nand its derivatives.

      \n

      If you teach people to 100% depend on the compiler, they will do it, cause it's\neasy. All you need to do is make the compiler shut up2. Giving up the\nintellectual masturbation about the memory safety will make you lose your edge\nover the time. When we get to the point of everyone being in the mindset\nmentioned above, who's going to maintain the compiler? This is the place where\nyou need to think about the memory safety and furthermore in a much more\ngeneral way than in your own projects, because it is the thing that everyone\nblindly believes in in the end.

      \n

      I'm not saying that everyone should give up Rust and think about their memory\nmanagement and potential memory issues. I'm just saying that going the easy way\nwill make people dull and they should think about it anyways, that's how the\nissue above has been discovered. If everyone walked past and didn't think about\nit, no one would discover this issue till it bit them hard.

      \n
      Standard library

      Even the standard library is littered with unsafe blocks that are prefixed\nwith comments in style:

      // SAFETY: …

      The fact that the casual Rust dev doesn't have to think much about safety,\ncause the compiler has their back, doesn't mean that the Rust compiler dev\ndoesn't either.

      I gotta admit that I adopted this concept in other languages (even in Python),\ncause you can encounter situations where it doesn't have to be clear why you\ncan do what you're doing.

      \n

      Development & design

      \n

      Development of Rust is… very fast. One positive is that they're trying to be as\nbackward compatible as possible at least by verifying against all the published\ncrates in the process. Of course, you cannot be backward compatible about fixing\nthe bugs that have been found, but such is life.

      \n

      Fast development cycle

      \n

      One of the negatives of the fast development cycle is the fact that they're\nusing the latest features already in the next release of the Rust. Yes, it is\nsomething that you can use for verifying and testing your own changes, but at\nthe same time it places a requirement of the latest release to compile the next\none.

      \n
      tip

      If you check gcc for example, they have a requirement of minimal version of\ncompiler that you need for the build. Though gcc's requirement is not so needy\nas the Rust one.

      \n

      One of the other negatives is the introduction of bugs. If you're pushing\nchanges, somewhat mindlessly, at such a fast pace, it is inevitable to introduce\na bunch bugs in the process. Checking the GitHub issue tracker with

      \n
      is:issue is:open label:C-bug label:T-compiler
      \n

      yields 2,224 open issues at the time of writing this post.

      \n

      RFCs

      \n

      You can find a lot of RFCs for the Rust. Some of them are more questionable\nthan the others. Fun thing is that a lot of them make it to the nightly builds,\nso they can be tested and polished off. Even the questionable ones… I'll leave\nfew examples for a better understanding.

      \n

      One of such features is the do yeet expression:

      \n
      #![feature(yeet_expr)]

      fn foo() -> Result<String, i32> {
      do yeet 4;
      }
      assert_eq!(foo(), Err(4));

      fn bar() -> Option<String> {
      do yeet;
      }
      assert_eq!(bar(), None);
      \n

      It allows you to “yeet” the errors out of the functions that return Result or\nOption.

      \n

      One of the more recent ones is\nthe ability to include Cargo manifests into the sources, so you can do something\nlike:

      \n
      #!/usr/bin/env cargo
      ---
      [dependencies]
      clap = { version = \"4.2\", features = [\"derive\"] }
      ---

      use clap::Parser;

      #[derive(Parser, Debug)]
      #[clap(version)]
      struct Args {
      #[clap(short, long, help = \"Path to config\")]
      config: Option<std::path::PathBuf>,
      }

      fn main() {
      let args = Args::parse();
      println!(\"{:?}\", args);
      }
      \n

      I would say you can get almost anything into the language…

      \n

      Community and hype train

      \n

      Rust community is a rather unique thing. A lot of people will hate me for this,\nbut I can't help, but to compare them to militant vegans. I'll go through some\nof the things related to it, so I can support my opinion at least.

      \n

      Rust is the best language. It is not. There is no best language, each has its\nown positives and negatives, you need to choose the language that's the most\nsuitable for your use case. There are areas where Rust excels, though I have\nto admit it's very close to being a universal hammer regardless of how suitable\nit is. There is a very steep learning curve to it, beginnings in Rust are very\npainful.

      \n

      Rewrite everything in Rust. Just no. There are multiple feedbacks on doing\nrewrites, it is very common to fix N bugs with a rewrite while introducing\nN + 1 other bugs in the process. It doesn't solve anything unless there are\nsome strong reasons to go with it. Majority of such suggested rewrites don't\nhave those reasons though.

      \n

      Language ‹x› is bad, though in Rust… Cherry-picking one specific pain point of\none language and reflecting how it is better in other language can go both ways.\nFor example it is rather easy to pick the limitations imposed by Rust compiler\nand show how it's possible in other languages 🤷‍♂️

      \n

      I don't mind any of those opinions, you're free to have them, as long as you\ndon't rub them in my face which is not the usual case… This experience makes it\njust worse for me, part of this post may be also influenced by this fact.

      \n

      Rust in Linux

      \n
      caution

      As someone who has seen the way Linux kernel is built in the RHEL ecosystem, how\ncomplex the whole thing is and how much resources you need to proceed, I have\nvery strong opinions on this topic.

      \n

      It took years of work to even “incorporate” Rust into the Linux codebase, just\nto get the “Hello World!”. I don't have anything against the idea of writing\ndrivers in the Rust, I bet it can catch a lot of common mistakes, but still\nintroducing Rust to the kernel is another step to enlarge the monster.

      \n

      I have to admit though that the Apple GPU driver for Linux written in Rust is\nquite impressive. Apart from that there are not so many benefits, yet…

      \n

      Packaging

      \n

      I'll divide the packaging into the packaging of the language itself and the\nprograms written in Rust.

      \n

      Let's start with the cargo itself though. Package managers of the languages\nusually get a lot of hate (you can take npm or pip as examples3). If\nyou've ever tried out Rust, I bet you already know where I'm going with this.\nYes, I mean the compilation times, or even Cargo downloading whole index of\ncrates just so you can update that one dependency (and 3 millions of indirect\ndeps). When I was doing AoC ‘22 in Rust, I've set up sccache right away on the\nfirst day.

      \n

      Let's move to the packaging of the Rust itself, it's tedious. Rust has a very\nfast development cycle and doesn't even try to make the builds backward\ncompatible. If there is a new release of Rust, there is a very high chance that\nyou cannot build that release with anything other than the latest Rust\nrelease. If you have ever touched the packaging, you know that this is something\nthat can cause a lot of problems, cause you need the second-to-latest version to\ncompile the latest version, don't forget that this applies inductively… People\nrunning Gentoo could tell you a lot about this.

      \n
      info

      Compiling the compilers takes usually more time than compiling the kernel\nitself…

      \n

      I cannot speak about packaging of Rust programs in other than RHEL-based\ndistros, though I can speak about RHEL ecosystem. Fedora packaging guidelines\nspecify that you need to build each and every dependency of the program\nseparately. I wanted to try out AlmaLinux and install Alacritty there and I\nfailed miserably. The solution that worked, consisted of ignoring the packaging\nguidelines, running cargo build and consuming the binaries afterwards.\nDependencies of the Rust programs are of a similar nature as JS dependencies.

      \n
      \n

      I'm tipping my fedora1 in the general direction of the maintainers of Rust\npackages in RHEL ecosystem. I wouldn't be able to do this without losing my\nsanity.

      \n
      \n

      Likes

      \n

      If you've come all the way here and you're a Rustacean, I believe I've managed\nto get your blood boiling, so it's time to finish this off by stuff I like about\nRust. I doubt I will be able to cover everything, but I can try at least. You\nhave to admit it's much easier to remember the bad stuff as opposed to the good.\n😉

      \n

      Workflow and toolchain

      \n

      I prefered using Rust for the Advent of Code and Codeforces as it provides\na rather easy way to test the solutions before running them with the challenge\ninput (or test runner). I can give an example from the Advent of Code:

      \n
      use aoc_2023::*;

      type Output1 = i32;
      type Output2 = Output1;

      struct DayXX {}
      impl Solution<Output1, Output2> for DayXX {
      fn new<P: AsRef<Path>>(pathname: P) -> Self {
      let lines: Vec<String> = file_to_lines(pathname);

      todo!()
      }

      fn part_1(&mut self) -> Output1 {
      todo!()
      }

      fn part_2(&mut self) -> Output2 {
      todo!()
      }
      }

      fn main() -> Result<()> {
      DayXX::main()
      }

      test_sample!(day_XX, DayXX, 42, 69);
      \n

      This was the skeleton I've used and the macro at the end is my own creation that\nexpands to:

      \n
      #[cfg(test)]
      mod day_XX {
      use super::*;

      #[test]
      fn part_1() {
      let path = DayXX::get_sample(1);
      let mut day = DayXX::new(path);
      assert_eq!(day.part_1(), 42);
      }

      #[test]
      fn part_2() {
      let path = DayXX::get_sample(2);
      let mut day = DayXX::new(path);
      assert_eq!(day.part_2(), 69);
      }
      }
      \n

      When you're solving the problem, all you need to do is switch between\ncargo test and cargo run to check the answer to either sample or the\nchallenge input itself.

      \n

      Introduce bacon and it gets even better. Bacon is a CLI tool that wraps around\nthe cargo and allows you to check, run, lint or run tests on each file save.\nIt's a very pleasant thing for a so-called compiler-assisted development.

      \n

      Speaking of linting from within the bacon, you cannot leave out the clippy.\nNot only it can whip your ass because of errors, but it can also produce a lot\nof helpful suggestions, for example passing slices by borrow instead of\nborrowing the Vec itself when you don't need it.

      \n

      Standard library

      \n

      There's a lot included in the standard library. It almost feels like you\nhave all you need4. I like placeholders (like todo!(), unreachable!(),\nunimplemented!()) to the extent of\nimplementing them as exceptions in C++.

      \n

      You can find almost anything. Though you can also hit some very weird issues\nwith some of the nuances of the type system.

      \n

      unsafe

      \n

      This might be something that people like to avoid as much as possible. However I\nthink that forming a habit of commenting posibly unsafe operations in any\nlanguage is a good habit, as I've mentioned above. You should be able to argue\nwhy you can do something safely, even if the compiler is not kicking your ass\nbecause of it.

      \n

      Excerpt of such comment from work:

      \n
      # SAFETY: Taking first package instead of specific package should be
      # safe, since we have put a requirement on »one« ‹upstream_project_url›
      # per Packit config, i.e. even if we're dealing with a monorepo, there
      # is only »one« upstream. If there is one upstream, there is only one
      # set of GPG keys that can be allowed.
      return self.downstream_config.packages[
      self.downstream_config._first_package
      ].allowed_gpg_keys
      \n

      Traits

      \n

      One of the other things I like are the traits. They are more restrictive than\ntemplates or concepts in C++, but they're doing their job pretty good. If you\nare building library and require multiple traits to be satisfied it means a lot\nof copy-paste, but that's soon to be fixed by the trait aliases.

      \n
      Comparing to other languages

      On Wikipedia I've seen trait being defined as a more restrictive type class as\nyou may know it from the Haskell for example. C++ isn't behind either with its\nconstraints and concepts. I would say that we can order them in the following\norder based on the complexity they can express:

      Rust's trait < Haskell's type class < C++'s concept
      \n

      You can also hit some issues, like me when trying to support conversions between\nunderlying numeric types of a 2D vectors or support for using an operator from\nboth sides (I couldn't get c * u to work in the same way as u * c because\nthe first one requires you to implement the trait of a built-in type).

      \n
      Implementation

      Implementing traits lies in

      impl SomeTrait for SomeStruct {
      // implementation goes here
      }

      One of the things I would love to see is being able to define the helper\nfunctions within the same block. As of now, the only things allowed are the ones\nthat are required by the trait, which in the end results in a randomly lying\nfunctions around (or in a implementation of the structure itself). I don't like\nthis mess at all…

      \n

      Influence of functional paradigm

      \n

      You can see a big influence of the functional paradigm. Not only in iterators,\nbut also in the other parts of the language. For example I prefer Option<T> or\nResult<T, E> to nulls and exceptions. Pattern matching together with\ncompiler both enforces handling of the errors and rather user-friendly way of\ndoing it.

      \n

      Not to mention .and_then() and such. However spending most of the time with\nthe AoC you get pretty annoyed of the repetitive .unwrap() during parsing,\nsince you are guaranteed correct input.

      \n

      Macros

      \n

      Macros are a very strong pro of the Rust. And no, we're not going to talk about\nthe procedural macros…

      \n

      As I've shown above I've managed to “tame” a lot of copy-paste in the tests for\nthe AoC by utilizing a macro that generated a very basic template for the tests.

      \n

      As I have mentioned the traits above, I cannot forget to give props to derive\nmacro that allows you to “deduce” the default implementation. It is very helpful\nfor a tedious tasks like implementing Debug (for printing out the structures)\nor comparisons, though with the comparisons you need to be careful about the\ndefault implementation, it has already bitten me once or twice.

      \n

      Summary

      \n

      Overall there are many things about the Rust I like and would love to see them\nimplemented in other languages. However there are also many things I don't like.\nNothing is exclusively black and white.

      \n

      Footnotes

      \n
        \n
      1. \n

        pun intended 2

        \n
      2. \n
      3. \n

        It's not that easy with the Rust compiler, but OK…

        \n
      4. \n
      5. \n

        not to even mention multiple different packaging standards Python has, which\nis borderline https://xkcd.com/927/

        \n
      6. \n
      7. \n

        unlike Python where there's whole universe in the language itself, yet there\nare essential things not present…

        \n
      8. \n
      \n
      ", "url": "https://blog.mfocko.xyz/blog/2024/01/28/rust-opinion", "title": "Mixed feelings on Rust", "summary": "Discussing my mixed feelings about the Rust language.\n", @@ -24,7 +24,7 @@ }, { "id": "https://blog.mfocko.xyz/blog/2023/08/02/copr", - "content_html": "

      When you decide to run Fedora on your VPS, you might get screwed over by using\nrandom repositories…

      \n

      When I “reserved” my VPS1 back in June '20, I slapped Fedora on it without\nthinking. I bet 99% of people would say that I'm crazy for doing such thing2,\nBUT I've been using Fedora on my PCs for some time already and it felt very\nstable and natural to just use, even for VPS.

      \n

      One of the first things I've done was setting up a mail server. You may guess\nwhat's the fun part about having a mail server… Yes, it's all the spam you\nreceive and only then you realize how much “crap” gets filtered on free mail\nservices. To battle this problem I chose to use\nrspamd that had CentOS support, but someone\nhad a Copr repository that I used to\ninstall it.

      \n

      How does Copr repositories work?

      \n

      If you have ever used Ubuntu, you might be familiar with the concept since it is\nvery close to PPAs.

      \n

      tl;dr of the whole process consists of

      \n
        \n
      1. enabling the Copr repository, and
      2. \n
      3. installing the desired package.
      4. \n
      \n

      So in shell you would do

      \n
      # dnf copr enable ‹copr-repository›
      # dnf install ‹package-from-the-repository›
      \n

      And… that's it! Nothing else needed! Simple, right? And literally same process\nas you would do for the PPA.

      \n
      AUR

      On the other hand, if you are familiar with the archLinux, you definitely know\nAUR and what it can do for you. Copr repository is pretty similar, but the\npackages are prebuilt in Copr and Copr repositories can carry the required\ndependencies for said packages, which simplifies the distribution, and can even\nhelp with installing singular packages (when you just need the dependency, not\neverything).

      \n

      My issue

      \n

      Now you might wonder how would I use it on my VPS. It's rather simple, once in\n6 months a new Fedora release comes out. And you need to upgrade to newer\nrelease… You don't need to do it right away and for such setup it probably isn't\neven recommended.

      \n
      tip

      Fedora releases are supported for a year, i.e. they live 6 months till the next\nrelease and then another 6 months till another release.

      Some people prefer to run one version “behind”. If you ever decide to run it on\nyour home server or in a similar setup, it might be a pretty good idea to\nfollow. I'm using the “latest greatest”, cause why not 😄

      One way or another, you still need to bump the release every six months, unless\nyou'd bump 2 releases at once every year, which would be a decision, since, at\nleast I, cannot see any benefits in it… You don't go for “stability”, cause once\na year you switch to the latest release and then, before you bump, you use one\nyear old software, so you're not even using the latest.

      \n

      Fast-forward 2 years in the future, new Fedora release came out (October '22)\nand I was doing an upgrade. Dependencies of the rspamd have been updated and\nrspamd builds in Copr have failed and no one fixed it. Cool, so now I can\nupgrade, but can either ignore the dependencies or uninstall the rspamd…

      \n

      How can Copr help?

      \n

      I have managed to find\nspecfile for the\nrspamd package that they use for CentOS. There were some files apart from the\nspecfile, so I had to make an SRPM locally and then… I just uploaded the SRPM\nto the Copr to\nbuild\nan RPM.

      \n

      I have switched the previous Copr repository for rspamd with my own and happily\nproceeded with the upgrade.

      \n

      Conclusion

      \n

      Copr is heavily used for testing builds on the upstream with\nPackit. However, as you can see, it is possible to use it\nvery well for packaging your own stuff and avoiding issues (such as the one\nI have described above), if need be.

      \n

      Footnotes

      \n
        \n
      1. \n

        vpsFree.cz

        \n
      2. \n
      3. \n

        Even though I've been running archLinux on some Raspberry Pi's and also\non one of my “home servers”, before getting the VPS. You could say I like\nto live on the edge…

        \n
      4. \n
      \n
      ", + "content_html": "

      When you decide to run Fedora on your VPS, you might get screwed over by using\nrandom repositories…

      \n

      When I “reserved” my VPS1 back in June '20, I slapped Fedora on it without\nthinking. I bet 99% of people would say that I'm crazy for doing such thing2,\nBUT I've been using Fedora on my PCs for some time already and it felt very\nstable and natural to just use, even for VPS.

      \n

      One of the first things I've done was setting up a mail server. You may guess\nwhat's the fun part about having a mail server… Yes, it's all the spam you\nreceive and only then you realize how much “crap” gets filtered on free mail\nservices. To battle this problem I chose to use\nrspamd that had CentOS support, but someone\nhad a Copr repository that I used to\ninstall it.

      \n

      How does Copr repositories work?

      \n

      If you have ever used Ubuntu, you might be familiar with the concept since it is\nvery close to PPAs.

      \n

      tl;dr of the whole process consists of

      \n
        \n
      1. enabling the Copr repository, and
      2. \n
      3. installing the desired package.
      4. \n
      \n

      So in shell you would do

      \n
      # dnf copr enable ‹copr-repository›
      # dnf install ‹package-from-the-repository›
      \n

      And… that's it! Nothing else needed! Simple, right? And literally same process\nas you would do for the PPA.

      \n
      AUR

      On the other hand, if you are familiar with the archLinux, you definitely know\nAUR and what it can do for you. Copr repository is pretty similar, but the\npackages are prebuilt in Copr and Copr repositories can carry the required\ndependencies for said packages, which simplifies the distribution, and can even\nhelp with installing singular packages (when you just need the dependency, not\neverything).

      \n

      My issue

      \n

      Now you might wonder how would I use it on my VPS. It's rather simple, once in\n6 months a new Fedora release comes out. And you need to upgrade to newer\nrelease… You don't need to do it right away and for such setup it probably isn't\neven recommended.

      \n
      tip

      Fedora releases are supported for a year, i.e. they live 6 months till the next\nrelease and then another 6 months till another release.

      Some people prefer to run one version “behind”. If you ever decide to run it on\nyour home server or in a similar setup, it might be a pretty good idea to\nfollow. I'm using the “latest greatest”, cause why not 😄

      One way or another, you still need to bump the release every six months, unless\nyou'd bump 2 releases at once every year, which would be a decision, since, at\nleast I, cannot see any benefits in it… You don't go for “stability”, cause once\na year you switch to the latest release and then, before you bump, you use one\nyear old software, so you're not even using the latest.

      \n

      Fast-forward 2 years in the future, new Fedora release came out (October '22)\nand I was doing an upgrade. Dependencies of the rspamd have been updated and\nrspamd builds in Copr have failed and no one fixed it. Cool, so now I can\nupgrade, but can either ignore the dependencies or uninstall the rspamd…

      \n

      How can Copr help?

      \n

      I have managed to find\nspecfile for the\nrspamd package that they use for CentOS. There were some files apart from the\nspecfile, so I had to make an SRPM locally and then… I just uploaded the SRPM\nto the Copr to\nbuild\nan RPM.

      \n

      I have switched the previous Copr repository for rspamd with my own and happily\nproceeded with the upgrade.

      \n

      Conclusion

      \n

      Copr is heavily used for testing builds on the upstream with\nPackit. However, as you can see, it is possible to use it\nvery well for packaging your own stuff and avoiding issues (such as the one\nI have described above), if need be.

      \n

      Footnotes

      \n
        \n
      1. \n

        vpsFree.cz

        \n
      2. \n
      3. \n

        Even though I've been running archLinux on some Raspberry Pi's and also\non one of my “home servers”, before getting the VPS. You could say I like\nto live on the edge…

        \n
      4. \n
      \n
      ", "url": "https://blog.mfocko.xyz/blog/2023/08/02/copr", "title": "How can Copr help with broken dependencies", "summary": "Copr comes to save you when maintainer doesn't care.", @@ -43,7 +43,7 @@ }, { "id": "https://blog.mfocko.xyz/blog/aoc-2022/4th-week", - "content_html": "

      Let's go through the fourth week of Advent of Code in Rust.

      \n

      Day 22: Monkey Map

      \n
      tl;dr

      Simulating a movement on a 2D map with given instructions. Map becomes a cube in\nthe 2nd part…

      \n
      Rant

      This was the most obnoxious problem of this year… and a lot of Rust issues have\nbeen hit.

      \n

      Solution

      \n

      It seems like a very simple problem to solve, but with very obnoxious changes in\nthe 2nd part and also it's relatively hard to decompose »properly«.

      \n

      Column iterator

      \n

      In the first part of the problem it was needed to know the boundaries of each\nrow and column, since I stored them in Vec<Vec<char>> and padded with spaces\nto ensure I have a rectangular 2D “array”. However when you wanted to go through\neach row and column to determine the boundaries, it was very easy to do for the\nrows (cause each row is a Vec element), but not for the columns, since they\nspan multiple rows.

      \n

      For this use case I have implemented my own column iterator:

      \n
      pub struct ColumnIterator<'a, T> {
      map: &'a [Vec<T>],
      column: usize,

      i: usize,
      }

      impl<'a, T> ColumnIterator<'a, T> {
      pub fn new(map: &'a [Vec<T>], column: usize) -> ColumnIterator<'a, T> {
      Self { map, column, i: 0 }
      }
      }

      impl<'a, T> Iterator for ColumnIterator<'a, T> {
      type Item = &'a T;

      fn next(&mut self) -> Option<Self::Item> {
      if self.i >= self.map.len() {
      return None;
      }

      self.i += 1;
      Some(&self.map[self.i - 1][self.column])
      }
      }
      \n

      Given this piece of an iterator, it is very easy to factor out the common\nfunctionality between the rows and columns into:

      \n
      let mut find_boundaries = |constructor: fn(usize) -> Orientation,
      iterator: &mut dyn Iterator<Item = &char>,
      upper_bound,
      i| {
      let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == ' ');
      let start = first_non_empty.next().unwrap().0 as isize;

      let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
      let end = last_non_empty.next().unwrap_or((upper_bound, &'_')).0 as isize;

      boundaries.insert(constructor(i), start..end);
      };
      \n

      And then use it as such:

      \n
      // construct all horizontal boundaries
      (0..map.len()).for_each(|row| {
      find_boundaries(
      Orientation::horizontal,
      &mut map[row].iter(),
      map[row].len(),
      row,
      );
      });

      // construct all vertical boundaries
      (0..map[0].len()).for_each(|col| {
      find_boundaries(
      Orientation::vertical,
      &mut ColumnIterator::new(&map, col),
      map.len(),
      col,
      );
      });
      \n

      Walking around the map

      \n

      Once the 2nd part got introduced, you start to think about a way how not to\ncopy-paste a lot of stuff (I haven't avoided it anyways…). In this problem, I've\nchosen to introduce a trait (i.e. interface) for 2D and 3D walker.

      \n
      trait Wrap: Clone {
      type State;

      // simulation
      fn is_blocked(&self) -> bool;
      fn step(&mut self, steps: isize);
      fn turn_left(&mut self);
      fn turn_right(&mut self);

      // movement
      fn next(&self) -> (Self::State, Direction);

      // final answer
      fn answer(&self) -> Output;
      }
      \n

      Each walker maintains its own state and also provides the functions that are\nused during the simulation. The “promised” methods are separated into:

      \n
        \n
      • simulation-related: that are used during the simulation from the .fold()
      • \n
      • movement-related: just a one method that holds most of the logic differences\nbetween 2D and 3D
      • \n
      • final answer: which extracts the proof of solution from the\nimplementation-specific walker
      • \n
      \n

      Both 2D and 3D versions borrow the original input and therefore you must\nannotate the lifetime of it:

      \n
      struct Wrap2D<'a> {
      input: &'a Input,
      position: Position,
      direction: Direction,
      }
      impl<'a> Wrap2D<'a> {
      fn new(input: &'a Input) -> Wrap2D<'a> {
      // …
      \n

      Problems

      \n

      I have used a lot of closures for this problem and once I introduced a parameter\nthat was of unknown type (apart from the fact it implements a specific trait), I\ngot suggested a “fix” for the compilation error that resulted in something that\nwas not possible to parse, cause it, more than likely, violated the grammar.

      \n

      In a similar fashion, I have been suggested changes that led to a code that\ndidn't make sense by just looking at it (there was no need to try the changes),\nfor example one suggested change in the closure parameter caused disapperance of\nthe parameter name. 😄

      \n

      Clippy

      \n

      I have to admit that Clippy was rather helpful here, I'll include two examples\nof rather smart suggestions.

      \n

      When writing the parsing for this problem, the first thing I have spotted on the\nchar was the .is_digit() function that takes a radix as a parameter. Clippy\nnoticed that I use radix = 10 and suggested switching to .is_ascii_digit()\nthat does exactly the same thing:

      \n
      -                .take_while(|c| c.is_digit(10))
      + .take_while(|c| c.is_ascii_digit())
      \n

      Another useful suggestion appeared when working with the iterators and I wanted\nto get the nnn-th element from it. You know the .skip(), you know the\n.next(), just “slap” them together and we're done for 😁 Well, I got\nsuggested to use .nth() that does exactly the combination of the two mentioned\nmethods on iterators:

      \n
      -            match it.clone().skip(skip).next().unwrap() {
      + match it.clone().nth(skip).unwrap() {
      \n

      Day 23: Unstable Diffusion

      \n
      tl;dr

      Simulating movement of elves around with a set of specific rules.

      \n

      Solution

      \n

      There's not much to mention since it's just a cellular automaton simulation\n(even though the AoC rules for cellular automatons usually get out of hand\n😉).

      \n

      Although I had a need to determine boundaries of the elves' positions and ended\nup with a nasty DRY violation. Knowing that you you're looking for maximum and\nminimum that are, of course, exactly the same except for initial values and\ncomparators, it looks like a rather simple fix, but typing in Rust is something\nelse, right? In the end I settled for a function that computes both boundaries\nwithout any duplication while using a closure:

      \n
      fn get_bounds(positions: &Input) -> (Vector2D<isize>, Vector2D<isize>) {
      let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {
      positions
      .iter()
      .fold(Vector2D::new(init, init), |acc, elf| {
      Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))
      })
      };

      (f(isize::MAX, &min::<isize>), f(isize::MIN, &max::<isize>))
      }
      \n

      This function returns a pair of 2D vectors that represent opposite points of the\nbounding rectangle of all elves.

      \n

      You might ask why would we need a closure and the answer is that positions\ncannot be captured from within the nested function, only via closure. One more\nfun fact on top of that is the type of the comparator

      \n
      &dyn Fn(isize, isize) -> isize
      \n

      Once we remove the dyn keyword, compiler yells at us and also includes a way\nhow to get a more thorough explanation of the error by running

      \n

      $ rustc --explain E0782

      \n

      which shows us

      \n

      Trait objects must include the dyn keyword.

      \n

      Erroneous code example:

      \n
      trait Foo {}
      fn test(arg: Box<Foo>) {} // error!
      \n

      Trait objects are a way to call methods on types that are not known until\nruntime but conform to some trait.

      \n

      Trait objects should be formed with Box<dyn Foo>, but in the code above\ndyn is left off.

      \n

      This makes it harder to see that arg is a trait object and not a\nsimply a heap allocated type called Foo.

      \n

      To fix this issue, add dyn before the trait name.

      \n
      trait Foo {}
      fn test(arg: Box<dyn Foo>) {} // ok!
      \n

      This used to be allowed before edition 2021, but is now an error.

      \n
      Rant

      Not all of the explanations are helpful though, in some cases they might be even\nmore confusing than helpful, since they address very simple use cases.

      As you can see, even in this case there are two sides to the explanations:

        \n
      • it explains why you need to use dyn, but
      • \n
      • it still mentions that trait objects need to be heap-allocated via Box<T>\nthat, as you can see in my snippet, does not apply here 😄 IMO it's\ncaused by the fact that we are borrowing it and therefore we don't need to\ncare about the size or whereabouts of it.
      • \n
      \n
      C++ parallel

      If you dive into the explanation above, you can notice that the Box<dyn Trait>\npattern is very helpful for using types that are not known during compile-time.\nYou would use a very similar approach in C++ when parsing some data structure\nfrom input (let's say JSON for example).

      On the other hand, in this case, it doesn't really make much sense, cause you\ncan clearly see that the types are known during the compile-time, which in\nC++ could be easily resolved by templating the helper function.

      \n

      Day 24: Blizzard Basin

      \n
      tl;dr

      Navigating your way through a basin with series of blizzards that move around\nyou as you move.

      \n
      caution

      It's second to last day and I went “bonkers” on the Rust 😄 Proceed to\nread Solution part on your own risk.

      \n

      Solution

      \n

      You are given a map with blizzards all over the place and you're supposed to\nfind the minimum time it requires you to walk through the basin without getting\nin any of the blizzards.

      \n

      Breakdown

      \n

      Relatively simple, yet a bit annoying, approach can be taken. It's technically\na shortest-path algorithm implementation with some relaxation restrictions and\nbeing able to stay on one position for some time, so each vertex of the graph\nis determined by the position on the map and the timestamp. I have chosen to\nuse Vector3D<usize>, since x and y attributes can be used for the position\nand, well, let's use z for a timestamp, cause why not, right? 😉

      \n

      Evaluating the blizzards

      \n
      caution

      I think that this is the most perverted abuse of the traits in the whole 4 weeks\nof AoC in Rust…

      \n

      The blizzards move along their respective directions in time and loop around in\ntheir respective row/column. Each vertex holds position and time, so we can\njust index the basin with the vertex itself, right? Yes, we can 😈

      \n
      Fun fact

      While writing this part, I've recognized unnecessary verbosity in the code and\ncleaned it up a bit. The changed version is shown here and the original was just\nmore verbose.

      \n

      I'll skip the boring parts of checking bounds and entry/exit of the basin 😉\nWe can easily calculate positions of the blizzards using a modular arithmetics:

      \n
      impl Index<Position> for Basin {
      type Output = char;

      fn index(&self, index: Position) -> &Self::Output {
      // ‹skipped boring parts›

      // We need to account for the loops of the blizzards
      let width = self.cols - 2;
      let height = self.rows - 2;

      let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;
      [
      (
      index.y() as usize,
      blizzard_origin(width, -1, index.z(), index.x()),
      '>',
      ),
      (
      index.y() as usize,
      blizzard_origin(width, 1, index.z(), index.x()),
      '<',
      ),
      (
      blizzard_origin(height, -1, index.z(), index.y()),
      index.x() as usize,
      'v',
      ),
      (
      blizzard_origin(height, 1, index.z(), index.y()),
      index.x() as usize,
      '^',
      ),
      ]
      .iter()
      .find_map(|&(y, x, direction)| {
      if self.map[y][x] == direction {
      Some(&self.map[y][x])
      } else {
      None
      }
      })
      .unwrap_or(&'.')
      }
      }
      \n

      As you can see, there is an expression for calculating the original position and\nit's used multiple times, so why not take it out to a lambda, right? 😉

      \n

      I couldn't get the rustfmt to format the for-loop nicely, so I've just\ndecided to go with iterating over an elements of a slice. I have used, once\nagain, a combination of two functions (find_map in this case) to do 2 things\nat once and at the end, if we haven't found any blizzard, we just return the\nempty space.

      \n

      I think it's a very nice (and naughty) way how to use the Index trait, don't\nyou think?

      \n

      Shortest-path algorithm

      \n

      For the shortest path you can choose and adjust any of the common shortest-path\nalgorithms, in my case, I have decided to use A* instead of Dijkstra's\nalgorithm, since it better reflects the cost function.

      \n
      Comparison of costs

      With the Dijkstra's algorithm I would proceed with the time attribute used as\na priority for the queue.

      Whereas with the A*, I have chosen to use both time and Manhattan distance\nthat promotes vertices closer to the exit and with a minimum time taken.

      \n

      Cost function is, of course, a closure 😉

      \n
      let cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());
      \n

      And also for checking the possible moves from the current vertex, I have\nimplemented, yet another, closure that yields an iterator with the next moves:

      \n
      let next_positions = |p| {
      [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]
      .iter()
      .filter_map(move |&(x, y, t)| {
      let next_p = p + Vector3D::new(x, y, t);

      if basin[next_p] == '.' {
      Some(next_p)
      } else {
      None
      }
      })
      };
      \n

      Min-heap

      \n

      In this case I had a need to use the priority queue taking the elements with the\nlowest cost as the prioritized ones. Rust only offers you the BinaryHeap and\nthat is a max-heap. One of the ways how to achieve a min-heap is to put the\nelements in wrapped in a Reverse (as is even showed in the linked docs of\nthe BinaryHeap). However the wrapping affects the type of the heap and also\npopping the most prioritized elements yields values wrapped in the Reverse.

      \n

      For this purpose I have just taken the max-heap and wrapped it as a whole in a\nseparate structure providing just the desired methods:

      \n
      use std::cmp::{Ord, Reverse};
      use std::collections::BinaryHeap;

      pub struct MinHeap<T> {
      heap: BinaryHeap<Reverse<T>>,
      }

      impl<T: Ord> MinHeap<T> {
      pub fn new() -> MinHeap<T> {
      MinHeap {
      heap: BinaryHeap::new(),
      }
      }

      pub fn push(&mut self, item: T) {
      self.heap.push(Reverse(item))
      }

      pub fn pop(&mut self) -> Option<T> {
      self.heap.pop().map(|Reverse(x)| x)
      }
      }

      impl<T: Ord> Default for MinHeap<T> {
      fn default() -> Self {
      Self::new()
      }
      }
      \n

      Rest is just the algorithm implementation which is not that interesting.

      \n

      Day 25: Full of Hot Air

      \n
      tl;dr

      Playing around with a numbers in a special base.

      \n

      Getting flashbacks to the IB111 Foundations of Programming… Very nice “problem”\nwith a rather easy solution, as the last day always seems to be.

      \n

      Solution

      \n

      Implementing 2 functions, converting from the SNAFU base and back to the SNAFU\nbase representation. Let's do a bit more though! I have implemented two functions:

      \n
        \n
      • from_snafu
      • \n
      • to_snafu
      • \n
      \n

      Now it is apparent that all I do is number to string and string to number. Hmm…\nthat sounds familiar, doesn't it? Let's introduce a structure for the SNAFU numbers\nand implement the traits that we need.

      \n

      Let's start with a structure:

      \n
      #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
      struct SNAFU {
      value: i64,
      }
      \n

      Converting from &str

      \n

      We will start by implementing the FromStr trait that will help us parse our input.\nThis is rather simple, I can just take the from_snafu function, copy-paste it\ninto the from_str method and the number I get will be wrapped in Result and\nSNAFU structure.

      \n

      Converting to String

      \n

      This is more fun. In some cases you need to implement only one trait and others\nare automatically implemented using that one trait. In our case, if you look in\nthe documentation, you can see that ToString trait is automatically implemented\nfor any type that implements Display trait.

      \n

      Let's implement the Display trait then. We should be able to use the to_snafu\nfunction and just take the self.value from the SNAFU structure.

      \n

      And for the convenience of tests, we can also implement a rather simple From<i64>\ntrait for the SNAFU.

      \n

      Adjusting the code

      \n

      After those changes we need to adjust the code and tests.

      \n

      Parsing of the input is very easy, before we have used the lines, now we parse\neverything:

      \n
           fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
      - file_to_lines(pathname)
      + file_to_structs(pathname)
      }
      \n

      Part 1 needs to be adjusted a bit too:

      \n
           fn part_1(input: &Input) -> Output {
      - to_snafu(input.iter().map(|s| from_snafu(s)).sum())
      + SNAFU::from(input.iter().map(|s| s.value).sum::<i64>()).to_string()
      }
      \n

      You can also see that it simplifies the meaning a bit and it is more explicit than\nthe previous versions.

      \n

      And for the tests:

      \n
           #[test]
      fn test_from() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(from_snafu(s), *n);
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(s.parse::<SNAFU>().unwrap().value, n);
      }
      }

      #[test]
      fn test_to() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(to_snafu(*n), s.to_string());
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(SNAFU::from(n).to_string(), s.to_string());
      }
      \n

      Summary

      \n

      Let's wrap the whole thing up! Keeping in mind both AoC and the Rust…

      \n

      \"Finished

      \n

      Advent of Code

      \n

      This year was quite fun, even though most of the solutions and posts came in\nlater on (cough in '23 cough). Day 22 was the most obnoxious one… And also\nit feels like I used priority queues and tree data structures a lot 👀

      \n

      with Rust

      \n

      I must admit that a lot of compiler warnings and errors were very useful. Even\nthough I still found some instances where they didn't help at all or cause even\nworse issues than I had. Compilation times have been addressed with the caching.

      \n

      Building my first tree data structure in Rust has been a very “interesting”\njourney. Being able to write a more generic BFS algorithm that allows you to not\nduplicate code while still mantaining the desired functionality contributes to\na very readable code.

      \n

      I am definitely much more aware of the basic things that bloated Python is\nmissing, yet Rust has them…

      \n

      Using explicit types and writing down placeholder functions with todo!()\nmacros is very pleasant, since it allows you to easily navigate the type system\nduring the development when you don't even need to be sure how are you going to\nput the smaller pieces together.

      \n

      I have used a plethora of traits and also implemented some of them to either be\nidiomatic, or exploit the syntactic sugar they offer. Deriving the default trait\nimplementation is also very helpful in a lot of cases, e.g. debugging output,\ncopying, equality comparison, etc.

      \n

      I confess to touching more “cursed” parts of the Rust, such as macros to\ndeclutter the copy-paste for tests or writing my own structures that need to\ncarry a lifetime for their own fields.

      \n

      tl;dr Relatively pleasant language until you hit brick wall 😉

      \n
      \n

      See you next year! Maybe in Rust, maybe not 🙃

      ", + "content_html": "

      Let's go through the fourth week of Advent of Code in Rust.

      \n

      Day 22: Monkey Map

      \n
      tl;dr

      Simulating a movement on a 2D map with given instructions. Map becomes a cube in\nthe 2nd part…

      \n
      Rant

      This was the most obnoxious problem of this year… and a lot of Rust issues have\nbeen hit.

      \n

      Solution

      \n

      It seems like a very simple problem to solve, but with very obnoxious changes in\nthe 2nd part and also it's relatively hard to decompose »properly«.

      \n

      Column iterator

      \n

      In the first part of the problem it was needed to know the boundaries of each\nrow and column, since I stored them in Vec<Vec<char>> and padded with spaces\nto ensure I have a rectangular 2D “array”. However when you wanted to go through\neach row and column to determine the boundaries, it was very easy to do for the\nrows (cause each row is a Vec element), but not for the columns, since they\nspan multiple rows.

      \n

      For this use case I have implemented my own column iterator:

      \n
      pub struct ColumnIterator<'a, T> {
      map: &'a [Vec<T>],
      column: usize,

      i: usize,
      }

      impl<'a, T> ColumnIterator<'a, T> {
      pub fn new(map: &'a [Vec<T>], column: usize) -> ColumnIterator<'a, T> {
      Self { map, column, i: 0 }
      }
      }

      impl<'a, T> Iterator for ColumnIterator<'a, T> {
      type Item = &'a T;

      fn next(&mut self) -> Option<Self::Item> {
      if self.i >= self.map.len() {
      return None;
      }

      self.i += 1;
      Some(&self.map[self.i - 1][self.column])
      }
      }
      \n

      Given this piece of an iterator, it is very easy to factor out the common\nfunctionality between the rows and columns into:

      \n
      let mut find_boundaries = |constructor: fn(usize) -> Orientation,
      iterator: &mut dyn Iterator<Item = &char>,
      upper_bound,
      i| {
      let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == ' ');
      let start = first_non_empty.next().unwrap().0 as isize;

      let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
      let end = last_non_empty.next().unwrap_or((upper_bound, &'_')).0 as isize;

      boundaries.insert(constructor(i), start..end);
      };
      \n

      And then use it as such:

      \n
      // construct all horizontal boundaries
      (0..map.len()).for_each(|row| {
      find_boundaries(
      Orientation::horizontal,
      &mut map[row].iter(),
      map[row].len(),
      row,
      );
      });

      // construct all vertical boundaries
      (0..map[0].len()).for_each(|col| {
      find_boundaries(
      Orientation::vertical,
      &mut ColumnIterator::new(&map, col),
      map.len(),
      col,
      );
      });
      \n

      Walking around the map

      \n

      Once the 2nd part got introduced, you start to think about a way how not to\ncopy-paste a lot of stuff (I haven't avoided it anyways…). In this problem, I've\nchosen to introduce a trait (i.e. interface) for 2D and 3D walker.

      \n
      trait Wrap: Clone {
      type State;

      // simulation
      fn is_blocked(&self) -> bool;
      fn step(&mut self, steps: isize);
      fn turn_left(&mut self);
      fn turn_right(&mut self);

      // movement
      fn next(&self) -> (Self::State, Direction);

      // final answer
      fn answer(&self) -> Output;
      }
      \n

      Each walker maintains its own state and also provides the functions that are\nused during the simulation. The “promised” methods are separated into:

      \n
        \n
      • simulation-related: that are used during the simulation from the .fold()
      • \n
      • movement-related: just a one method that holds most of the logic differences\nbetween 2D and 3D
      • \n
      • final answer: which extracts the proof of solution from the\nimplementation-specific walker
      • \n
      \n

      Both 2D and 3D versions borrow the original input and therefore you must\nannotate the lifetime of it:

      \n
      struct Wrap2D<'a> {
      input: &'a Input,
      position: Position,
      direction: Direction,
      }
      impl<'a> Wrap2D<'a> {
      fn new(input: &'a Input) -> Wrap2D<'a> {
      // …
      \n

      Problems

      \n

      I have used a lot of closures for this problem and once I introduced a parameter\nthat was of unknown type (apart from the fact it implements a specific trait), I\ngot suggested a “fix” for the compilation error that resulted in something that\nwas not possible to parse, cause it, more than likely, violated the grammar.

      \n

      In a similar fashion, I have been suggested changes that led to a code that\ndidn't make sense by just looking at it (there was no need to try the changes),\nfor example one suggested change in the closure parameter caused disapperance of\nthe parameter name. 😄

      \n

      Clippy

      \n

      I have to admit that Clippy was rather helpful here, I'll include two examples\nof rather smart suggestions.

      \n

      When writing the parsing for this problem, the first thing I have spotted on the\nchar was the .is_digit() function that takes a radix as a parameter. Clippy\nnoticed that I use radix = 10 and suggested switching to .is_ascii_digit()\nthat does exactly the same thing:

      \n
      -                .take_while(|c| c.is_digit(10))
      + .take_while(|c| c.is_ascii_digit())
      \n

      Another useful suggestion appeared when working with the iterators and I wanted\nto get the nnn-th element from it. You know the .skip(), you know the\n.next(), just “slap” them together and we're done for 😁 Well, I got\nsuggested to use .nth() that does exactly the combination of the two mentioned\nmethods on iterators:

      \n
      -            match it.clone().skip(skip).next().unwrap() {
      + match it.clone().nth(skip).unwrap() {
      \n

      Day 23: Unstable Diffusion

      \n
      tl;dr

      Simulating movement of elves around with a set of specific rules.

      \n

      Solution

      \n

      There's not much to mention since it's just a cellular automaton simulation\n(even though the AoC rules for cellular automatons usually get out of hand\n😉).

      \n

      Although I had a need to determine boundaries of the elves' positions and ended\nup with a nasty DRY violation. Knowing that you you're looking for maximum and\nminimum that are, of course, exactly the same except for initial values and\ncomparators, it looks like a rather simple fix, but typing in Rust is something\nelse, right? In the end I settled for a function that computes both boundaries\nwithout any duplication while using a closure:

      \n
      fn get_bounds(positions: &Input) -> (Vector2D<isize>, Vector2D<isize>) {
      let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {
      positions
      .iter()
      .fold(Vector2D::new(init, init), |acc, elf| {
      Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))
      })
      };

      (f(isize::MAX, &min::<isize>), f(isize::MIN, &max::<isize>))
      }
      \n

      This function returns a pair of 2D vectors that represent opposite points of the\nbounding rectangle of all elves.

      \n

      You might ask why would we need a closure and the answer is that positions\ncannot be captured from within the nested function, only via closure. One more\nfun fact on top of that is the type of the comparator

      \n
      &dyn Fn(isize, isize) -> isize
      \n

      Once we remove the dyn keyword, compiler yells at us and also includes a way\nhow to get a more thorough explanation of the error by running

      \n

      $ rustc --explain E0782

      \n

      which shows us

      \n

      Trait objects must include the dyn keyword.

      \n

      Erroneous code example:

      \n
      trait Foo {}
      fn test(arg: Box<Foo>) {} // error!
      \n

      Trait objects are a way to call methods on types that are not known until\nruntime but conform to some trait.

      \n

      Trait objects should be formed with Box<dyn Foo>, but in the code above\ndyn is left off.

      \n

      This makes it harder to see that arg is a trait object and not a\nsimply a heap allocated type called Foo.

      \n

      To fix this issue, add dyn before the trait name.

      \n
      trait Foo {}
      fn test(arg: Box<dyn Foo>) {} // ok!
      \n

      This used to be allowed before edition 2021, but is now an error.

      \n
      Rant

      Not all of the explanations are helpful though, in some cases they might be even\nmore confusing than helpful, since they address very simple use cases.

      As you can see, even in this case there are two sides to the explanations:

        \n
      • it explains why you need to use dyn, but
      • \n
      • it still mentions that trait objects need to be heap-allocated via Box<T>\nthat, as you can see in my snippet, does not apply here 😄 IMO it's\ncaused by the fact that we are borrowing it and therefore we don't need to\ncare about the size or whereabouts of it.
      • \n
      \n
      C++ parallel

      If you dive into the explanation above, you can notice that the Box<dyn Trait>\npattern is very helpful for using types that are not known during compile-time.\nYou would use a very similar approach in C++ when parsing some data structure\nfrom input (let's say JSON for example).

      On the other hand, in this case, it doesn't really make much sense, cause you\ncan clearly see that the types are known during the compile-time, which in\nC++ could be easily resolved by templating the helper function.

      \n

      Day 24: Blizzard Basin

      \n
      tl;dr

      Navigating your way through a basin with series of blizzards that move around\nyou as you move.

      \n
      caution

      It's second to last day and I went “bonkers” on the Rust 😄 Proceed to\nread Solution part on your own risk.

      \n

      Solution

      \n

      You are given a map with blizzards all over the place and you're supposed to\nfind the minimum time it requires you to walk through the basin without getting\nin any of the blizzards.

      \n

      Breakdown

      \n

      Relatively simple, yet a bit annoying, approach can be taken. It's technically\na shortest-path algorithm implementation with some relaxation restrictions and\nbeing able to stay on one position for some time, so each vertex of the graph\nis determined by the position on the map and the timestamp. I have chosen to\nuse Vector3D<usize>, since x and y attributes can be used for the position\nand, well, let's use z for a timestamp, cause why not, right? 😉

      \n

      Evaluating the blizzards

      \n
      caution

      I think that this is the most perverted abuse of the traits in the whole 4 weeks\nof AoC in Rust…

      \n

      The blizzards move along their respective directions in time and loop around in\ntheir respective row/column. Each vertex holds position and time, so we can\njust index the basin with the vertex itself, right? Yes, we can 😈

      \n
      Fun fact

      While writing this part, I've recognized unnecessary verbosity in the code and\ncleaned it up a bit. The changed version is shown here and the original was just\nmore verbose.

      \n

      I'll skip the boring parts of checking bounds and entry/exit of the basin 😉\nWe can easily calculate positions of the blizzards using a modular arithmetics:

      \n
      impl Index<Position> for Basin {
      type Output = char;

      fn index(&self, index: Position) -> &Self::Output {
      // ‹skipped boring parts›

      // We need to account for the loops of the blizzards
      let width = self.cols - 2;
      let height = self.rows - 2;

      let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;
      [
      (
      index.y() as usize,
      blizzard_origin(width, -1, index.z(), index.x()),
      '>',
      ),
      (
      index.y() as usize,
      blizzard_origin(width, 1, index.z(), index.x()),
      '<',
      ),
      (
      blizzard_origin(height, -1, index.z(), index.y()),
      index.x() as usize,
      'v',
      ),
      (
      blizzard_origin(height, 1, index.z(), index.y()),
      index.x() as usize,
      '^',
      ),
      ]
      .iter()
      .find_map(|&(y, x, direction)| {
      if self.map[y][x] == direction {
      Some(&self.map[y][x])
      } else {
      None
      }
      })
      .unwrap_or(&'.')
      }
      }
      \n

      As you can see, there is an expression for calculating the original position and\nit's used multiple times, so why not take it out to a lambda, right? 😉

      \n

      I couldn't get the rustfmt to format the for-loop nicely, so I've just\ndecided to go with iterating over an elements of a slice. I have used, once\nagain, a combination of two functions (find_map in this case) to do 2 things\nat once and at the end, if we haven't found any blizzard, we just return the\nempty space.

      \n

      I think it's a very nice (and naughty) way how to use the Index trait, don't\nyou think?

      \n

      Shortest-path algorithm

      \n

      For the shortest path you can choose and adjust any of the common shortest-path\nalgorithms, in my case, I have decided to use A* instead of Dijkstra's\nalgorithm, since it better reflects the cost function.

      \n
      Comparison of costs

      With the Dijkstra's algorithm I would proceed with the time attribute used as\na priority for the queue.

      Whereas with the A*, I have chosen to use both time and Manhattan distance\nthat promotes vertices closer to the exit and with a minimum time taken.

      \n

      Cost function is, of course, a closure 😉

      \n
      let cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());
      \n

      And also for checking the possible moves from the current vertex, I have\nimplemented, yet another, closure that yields an iterator with the next moves:

      \n
      let next_positions = |p| {
      [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]
      .iter()
      .filter_map(move |&(x, y, t)| {
      let next_p = p + Vector3D::new(x, y, t);

      if basin[next_p] == '.' {
      Some(next_p)
      } else {
      None
      }
      })
      };
      \n

      Min-heap

      \n

      In this case I had a need to use the priority queue taking the elements with the\nlowest cost as the prioritized ones. Rust only offers you the BinaryHeap and\nthat is a max-heap. One of the ways how to achieve a min-heap is to put the\nelements in wrapped in a Reverse (as is even showed in the linked docs of\nthe BinaryHeap). However the wrapping affects the type of the heap and also\npopping the most prioritized elements yields values wrapped in the Reverse.

      \n

      For this purpose I have just taken the max-heap and wrapped it as a whole in a\nseparate structure providing just the desired methods:

      \n
      use std::cmp::{Ord, Reverse};
      use std::collections::BinaryHeap;

      pub struct MinHeap<T> {
      heap: BinaryHeap<Reverse<T>>,
      }

      impl<T: Ord> MinHeap<T> {
      pub fn new() -> MinHeap<T> {
      MinHeap {
      heap: BinaryHeap::new(),
      }
      }

      pub fn push(&mut self, item: T) {
      self.heap.push(Reverse(item))
      }

      pub fn pop(&mut self) -> Option<T> {
      self.heap.pop().map(|Reverse(x)| x)
      }
      }

      impl<T: Ord> Default for MinHeap<T> {
      fn default() -> Self {
      Self::new()
      }
      }
      \n

      Rest is just the algorithm implementation which is not that interesting.

      \n

      Day 25: Full of Hot Air

      \n
      tl;dr

      Playing around with a numbers in a special base.

      \n

      Getting flashbacks to the IB111 Foundations of Programming… Very nice “problem”\nwith a rather easy solution, as the last day always seems to be.

      \n

      Solution

      \n

      Implementing 2 functions, converting from the SNAFU base and back to the SNAFU\nbase representation. Let's do a bit more though! I have implemented two functions:

      \n
        \n
      • from_snafu
      • \n
      • to_snafu
      • \n
      \n

      Now it is apparent that all I do is number to string and string to number. Hmm…\nthat sounds familiar, doesn't it? Let's introduce a structure for the SNAFU numbers\nand implement the traits that we need.

      \n

      Let's start with a structure:

      \n
      #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
      struct SNAFU {
      value: i64,
      }
      \n

      Converting from &str

      \n

      We will start by implementing the FromStr trait that will help us parse our input.\nThis is rather simple, I can just take the from_snafu function, copy-paste it\ninto the from_str method and the number I get will be wrapped in Result and\nSNAFU structure.

      \n

      Converting to String

      \n

      This is more fun. In some cases you need to implement only one trait and others\nare automatically implemented using that one trait. In our case, if you look in\nthe documentation, you can see that ToString trait is automatically implemented\nfor any type that implements Display trait.

      \n

      Let's implement the Display trait then. We should be able to use the to_snafu\nfunction and just take the self.value from the SNAFU structure.

      \n

      And for the convenience of tests, we can also implement a rather simple From<i64>\ntrait for the SNAFU.

      \n

      Adjusting the code

      \n

      After those changes we need to adjust the code and tests.

      \n

      Parsing of the input is very easy, before we have used the lines, now we parse\neverything:

      \n
           fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
      - file_to_lines(pathname)
      + file_to_structs(pathname)
      }
      \n

      Part 1 needs to be adjusted a bit too:

      \n
           fn part_1(input: &Input) -> Output {
      - to_snafu(input.iter().map(|s| from_snafu(s)).sum())
      + SNAFU::from(input.iter().map(|s| s.value).sum::<i64>()).to_string()
      }
      \n

      You can also see that it simplifies the meaning a bit and it is more explicit than\nthe previous versions.

      \n

      And for the tests:

      \n
           #[test]
      fn test_from() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(from_snafu(s), *n);
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(s.parse::<SNAFU>().unwrap().value, n);
      }
      }

      #[test]
      fn test_to() {
      - for (n, s) in EXAMPLES.iter() {
      - assert_eq!(to_snafu(*n), s.to_string());
      + for (&n, s) in EXAMPLES.iter() {
      + assert_eq!(SNAFU::from(n).to_string(), s.to_string());
      }
      \n

      Summary

      \n

      Let's wrap the whole thing up! Keeping in mind both AoC and the Rust…

      \n

      \"Finished

      \n

      Advent of Code

      \n

      This year was quite fun, even though most of the solutions and posts came in\nlater on (cough in '23 cough). Day 22 was the most obnoxious one… And also\nit feels like I used priority queues and tree data structures a lot 👀

      \n

      with Rust

      \n

      I must admit that a lot of compiler warnings and errors were very useful. Even\nthough I still found some instances where they didn't help at all or cause even\nworse issues than I had. Compilation times have been addressed with the caching.

      \n

      Building my first tree data structure in Rust has been a very “interesting”\njourney. Being able to write a more generic BFS algorithm that allows you to not\nduplicate code while still mantaining the desired functionality contributes to\na very readable code.

      \n

      I am definitely much more aware of the basic things that bloated Python is\nmissing, yet Rust has them…

      \n

      Using explicit types and writing down placeholder functions with todo!()\nmacros is very pleasant, since it allows you to easily navigate the type system\nduring the development when you don't even need to be sure how are you going to\nput the smaller pieces together.

      \n

      I have used a plethora of traits and also implemented some of them to either be\nidiomatic, or exploit the syntactic sugar they offer. Deriving the default trait\nimplementation is also very helpful in a lot of cases, e.g. debugging output,\ncopying, equality comparison, etc.

      \n

      I confess to touching more “cursed” parts of the Rust, such as macros to\ndeclutter the copy-paste for tests or writing my own structures that need to\ncarry a lifetime for their own fields.

      \n

      tl;dr Relatively pleasant language until you hit brick wall 😉

      \n
      \n

      See you next year! Maybe in Rust, maybe not 🙃

      ", "url": "https://blog.mfocko.xyz/blog/aoc-2022/4th-week", "title": "4th week of Advent of Code '22 in Rust", "summary": "Surviving fourth week in Rust.", @@ -60,7 +60,7 @@ }, { "id": "https://blog.mfocko.xyz/blog/aoc-2022/3rd-week", - "content_html": "

      Let's go through the third week of Advent of Code in Rust.

      \n

      Day 15: Beacon Exclusion Zone

      \n
      tl;dr

      Triangulating a distress beacon based on the information from the sensors.

      \n

      Solution

      \n

      Relatively easy thing to implement, no major Rust issues hit.

      \n

      Day 16: Proboscidea Volcanium

      \n
      tl;dr

      Finding a max flow in a graph given some time constraints.

      \n

      Solution

      \n

      I have used some interesting things to implement this and make it easier for me.

      \n

      Indexing in graph

      \n

      I have come across a situation where I needed to keep more information regarding\nthe graph… In that case you can, of course, create a structure and keep it in,\nbut once you have multiple members in the structure it gets harder to work with\nsince you need to address the fields in the structure. When you work with graph,\nyou frequently need to access the vertices and in this case it felt a lot easier\nto implement the indexing in a graph, rather than explicitly access the\nunderlying data structure.

      \n

      Here you can see a rather short snippet from the solution that allows you to\n“index” the graph:

      \n
      impl Index<&str> for Graph {
      type Output = Vertex;

      fn index(&self, index: &str) -> &Self::Output {
      &self.g[index]
      }
      }
      \n

      Cartesian product

      \n

      During the implementation I had to utilize Floyd-Warshall algorithm for finding\nthe shortest path between pairs of vertices and utilized the iproduct! macro\nfrom the itertools. It is a very useful higher-order function that allows\nyou to keep the nesting of the loops at a minimum level while still maintaining\nthe same functionality.

      \n

      “Implementing” an iterator

      \n

      For the second part, you get to split the work between 2 actors. That way you\ncan achieve higher efficiency of the whole process that you're planning, but it\nalso makes it harder to evaluate algorithmically, since you need to check the\ndifferent ways the work can be split.

      \n

      Being affected by functional programming brain damage™️, I have chosen to\ndo this part by function that returns an iterator over the possible ways:

      \n
      fn pairings(
      valves: &BTreeSet<String>,
      ) -> impl Iterator<Item = (BTreeSet<String>, BTreeSet<String>)> + '_ {
      let mapping = valves.iter().collect_vec();

      let max_mask = 1 << (valves.len() - 1);

      (0..max_mask).map(move |mask| {
      let mut elephant = BTreeSet::new();
      let mut human = BTreeSet::new();

      for (i, &v) in mapping.iter().enumerate() {
      if (mask & (1 << i)) == 0 {
      human.insert(v.clone());
      } else {
      elephant.insert(v.clone());
      }
      }

      (human, elephant)
      })
      }
      \n

      Day 17: Pyroclastic Flow

      \n
      tl;dr

      Simulating an autonomous Tetris where pieces get affected by a series of jets of\nhot gas.

      \n

      Solution

      \n

      Similarly to the previous day I have created some iterators 😄

      \n

      Collision detection

      \n

      Once you need to check for collisions it is very helpful to be able to just\niterate through the positions that can actually collide with the wall or other\npiece.

      \n

      To get the desired behaviour, you can just compose few smaller functions:

      \n
      fn occupied(shape: &[Vec<char>]) -> impl Iterator<Item = Position> + '_ {
      shape.iter().enumerate().flat_map(|(y, row)| {
      row.iter().enumerate().filter_map(move |(x, c)| {
      if c == &'#' {
      Some(Vector2D::new(x as isize, y as isize))
      } else {
      None
      }
      })
      })
      }
      \n

      In the end, we get relative positions which we can adjust later when given the\nspecific positions from iterator. You can see some interesting parts in this:

      \n
        \n
      • .enumerate() allows us to get both the indices (coordinates) and the line\nor, later on, the character itself,
      • \n
      • .flat_map() flattens the iterator, i.e. when we return another iterator,\nthey just get chained instead of iterating over iterators (which sounds pretty\ndisturbing, doesn't it?),
      • \n
      • and finally .filter_map() which is pretty similar to the “basic” .map()\nwith a one, key, difference that it expects the items of an iterator to be\nmapped to an Option<T> from which it ignores nothing (as in None 😉)\nand also unwraps the values from Some(…).
      • \n
      \n

      Infinite iterator

      \n

      In the solution we cycle through both Tetris-like shapes that fall down and the\njets that move our pieces around. Initially I have implemented my own infinite\niterator that just yields the indices. It is a very simple, yet powerful, piece\nof code:

      \n
      struct InfiniteIndex {
      size: usize,
      i: usize,
      }

      impl InfiniteIndex {
      fn new(size: usize) -> InfiniteIndex {
      InfiniteIndex { size, i: size - 1 }
      }
      }

      impl Iterator for InfiniteIndex {
      type Item = usize;

      fn next(&mut self) -> Option<Self::Item> {
      self.i = (self.i + 1) % self.size;
      Some(self.i)
      }
      }
      \n

      However when I'm looking at the code now, it doesn't really make much sense…\nGuess what, we can use a built-in function that is implemented on iterators for\nthat! The function is called .cycle()

      \n

      On the other hand, I am not going to switch to that function, since it would\nintroduce an another myriad of issues caused by the fact that I create iterators\nright away in the constructor of my structure and the iterators would borrow\nboth the jets and shapes which would introduce a lifetime dependency into the\nstructure.

      \n

      Day 18: Boiling Boulders

      \n
      tl;dr

      Let's compute a surface area of some obsidian approximated via coordinates of\ncubes.

      \n

      Solution

      \n

      This day is kinda interesting, because it shows how easily you can complicate the\nproblem and also how much can you screw yourself over with the optimization and\n“smart” approach.

      \n

      For the first part you need to find the surface area of an obsidian that is\napproximated by cubes. Now, that is a very easy thing to do, just keep the track\nof already added cubes, and check if the newly added cube touches any face of any\nother cube. Simple, and with a BTreeSet relatively efficient way to do it.

      \n

      However the second part lets you on a secret that there may be some surface area\nfrom the “inside” too and you want to know only the one from the outside of the\nobsidian. I have seen some solutions later, but if you check your data, you might\nnotice that the bounding box of all the cubes isn't that big at all. Therefore I\nchose to pre-construct the box beforehand, fill in the cubes and then just run a\nBFS turning all the lava on the outside into the air. Now you just need to check\ncubes and count how many of their faces touch the air.

      \n

      Day 19: Not Enough Minerals

      \n
      tl;dr

      Finding out the best strategy for building robots to collect geodes.

      \n

      Solution

      \n

      Not much interesting stuff to mention apart from the suggestion to never believe\nthat the default implementation given by derive macro is what you want, it\ndoesn't have to be. 😄

      \n

      Day 20: Grove Positioning System

      \n
      tl;dr

      Shuffling around the circular linked list to find the coordinates.

      \n

      Now, small rant for this day is in place. They've never mentioned that coordinates\ncan repeat and therefore the values are non-unique. This is something that did\nnot happen in the given sample, but was present in the user input. It took »a lot«\nto realize that this is the issue.

      \n

      Solution

      \n

      I have tried implementing a circular linked list for this… and I have failed\nmiserably. To be fair, I still have no clue why. It was “fun” to play around with\nthe Rc<RefCell<T>>. In the end I failed on wrong answer. I have also encountered\na rather interesting issue with .borrow_mut() method being used on Rc<RefCell<T>>.

      \n

      .borrow_mut()

      \n

      Consider the following snippet of the code (taken from the documentation):

      \n
      use std::cell::{RefCell, RefMut};
      use std::collections::HashMap;
      use std::rc::Rc;
      // use std::borrow::BorrowMut;

      fn main() {
      let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
      // Create a new block to limit the scope of the dynamic borrow
      {
      let mut map: RefMut<_> = shared_map.borrow_mut();
      map.insert(\"africa\", 92388);
      map.insert(\"kyoto\", 11837);
      map.insert(\"piccadilly\", 11826);
      map.insert(\"marbles\", 38);
      }

      // Note that if we had not let the previous borrow of the cache fall out
      // of scope then the subsequent borrow would cause a dynamic thread panic.
      // This is the major hazard of using `RefCell`.
      let total: i32 = shared_map.borrow().values().sum();
      println!(\"{total}\");
      }
      \n

      We allocate a hash map on the heap and then in the inner block, we borrow it as\na mutable reference, so that we can use it.

      \n
      note

      It is a very primitive example for Rc<RefCell<T>> and mutable borrow.

      \n

      If you uncomment the 4th line with use std::borrow::BorrowMut;, you cannot\ncompile the code anymore, because of

      \n
         Compiling playground v0.0.1 (/playground)
      error[E0308]: mismatched types
      --> src/main.rs:10:34
      |
      10 | let mut map: RefMut<_> = shared_map.borrow_mut();
      | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference
      | |
      | expected due to this
      |
      = note: expected struct `RefMut<'_, _>`
      found mutable reference `&mut Rc<RefCell<HashMap<_, _>>>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:11:13
      |
      11 | map.insert(\"africa\", 92388);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:12:13
      |
      12 | map.insert(\"kyoto\", 11837);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:13:13
      |
      13 | map.insert(\"piccadilly\", 11826);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:14:13
      |
      14 | map.insert(\"marbles\", 38);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      Some errors have detailed explanations: E0308, E0599.
      For more information about an error, try `rustc --explain E0308`.
      error: could not compile `playground` due to 5 previous errors
      \n

      It might seem a bit ridiculous. However, I got to a point where the compiler\nsuggested use std::borrow::BorrowMut; and it resulted in breaking parts of the\ncode that worked previously. I think it may be a good idea to go over what is\nhappening here.

      \n
      .borrow_mut() on Rc<RefCell<T>>
      \n

      Let's consider a variable x of type Rc<RefCell<T>>. What happens when you\ncall .borrow_mut() on it? We can look at the Rc type, and… hang on! There is\nneither .borrow_mut() method or BorrowMut trait implemented. How can we do it\nthen?

      \n

      Let's go further and we can see that RefCell<T> implements a .borrow_mut()\nmethod. OK, but how can we call it on the Rc<T>? Easily! Rc<T> implements\nDeref<T> and therefore you can call methods on Rc<T> objects as if they were\nT objects. If we read on Deref coercion, we can see the following:

      \n
      \n

      If T implements Deref<Target = U>, …:

      \n
        \n
      • \n
      • T implicitly implements all the (immutable) methods of the type U.
      • \n
      \n
      \n

      What is the requirement for the .borrow_mut() on RefCell<T>? Well, it needs\n&self, so the Deref implements the .borrow_mut() for the Rc<RefCell<T>>.

      \n
      BorrowMut trait
      \n

      I have not been able to find a lot on this trait. My guess is that it provides a\nmethod instead of a syntactic sugar (&mut x) for the mutable borrow. And also\nit provides default implementations for the types:

      \n
      impl BorrowMut<str> for String

      impl<T> BorrowMut<T> for &mut T
      where
      T: ?Sized,

      impl<T> BorrowMut<T> for T
      where
      T: ?Sized,

      impl<T, A> BorrowMut<[T]> for Vec<T, A>
      where
      A: Allocator,

      impl<T, A> BorrowMut<T> for Box<T, A>
      where
      A: Allocator,
      T: ?Sized,

      impl<T, const N: usize> BorrowMut<[T]> for [T; N]
      \n
      Conflict
      \n

      Now the question is why did it break the code… My first take was that the type\nRc<RefCell<T>> has some specialized implementation of the .borrow_mut() and\nthe use overrides it with the default, which is true in a sense. However\nthere is no specialized implementation. Let's have a look at the trait and the\ntype signature on the RefCell<T>:

      \n
      // trait
      pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
      where
      Borrowed: ?Sized,
      {
      fn borrow_mut(&mut self) -> &mut Borrowed;
      }

      // ‹RefCell<T>.borrow_mut()› type signature
      pub fn borrow_mut(&self) -> RefMut<'_, T>
      \n

      I think that we can definitely agree on the fact that RefMut<'_, T> is not the\nRefCell<T>.

      \n

      In my opinion, RefCell<T> implements a separate .borrow_mut() rather\nthan implementing the interface, because it cannot satisfy the type requirements\nof the trait.

      \n
      caution

      I wonder how are we expected to deal with this conflict, if and when, we need\nboth the .borrow_mut() of the trait and .borrow_mut() of the RefCell<T>.

      \n
      Fun fact

      I was suggested by the compiler to do use std::borrow::BorrowMut; and break the\ncode.

      So much for the almighty and helpful compiler…

      \n

      Day 21: Monkey Math

      \n
      tl;dr

      Computing an expression tree and then also finding ideal value for a node.

      \n

      Solution

      \n

      Relatively simple, until you get to the 2nd part where you start to practice\na lot of the copy-paste. I have managed to sneak some perverted stuff in there\nthough :) Let's go through the details.

      \n

      Default trait

      \n

      For the first time and twice I had a need to have a default value for my types,\nenumerations in this case. Rust offers a very nice trait1 that is described\nas:

      \n
      \n

      A trait for giving a type a useful default value.

      \n
      \n

      I guess it sums it up nicely. The more interesting part about this is the fact\nthat you can use the macro machinery to save yourself some typing. If you have\nenumeration of which the default value doesn't bear any parameter, you can just\ndo2:

      \n
      #[derive(Default)]
      enum Color {
      #[default]
      White,
      Gray,
      Black,
      }
      \n

      Abusing negation

      \n

      If you want to use a unary minus operator on your own type, you can implement\na Neg trait3. I was dealing with a binary tree and needed a way how to look\nat the other side, so I have just implemented the negation for flipping between\nleft and right 😄

      \n

      Footnotes

      \n
        \n
      1. \n

        Default docs

        \n
      2. \n
      3. \n

        Pardon my example from the graph algorithms ;)

        \n
      4. \n
      5. \n

        Neg docs

        \n
      6. \n
      \n
      ", + "content_html": "

      Let's go through the third week of Advent of Code in Rust.

      \n

      Day 15: Beacon Exclusion Zone

      \n
      tl;dr

      Triangulating a distress beacon based on the information from the sensors.

      \n

      Solution

      \n

      Relatively easy thing to implement, no major Rust issues hit.

      \n

      Day 16: Proboscidea Volcanium

      \n
      tl;dr

      Finding a max flow in a graph given some time constraints.

      \n

      Solution

      \n

      I have used some interesting things to implement this and make it easier for me.

      \n

      Indexing in graph

      \n

      I have come across a situation where I needed to keep more information regarding\nthe graph… In that case you can, of course, create a structure and keep it in,\nbut once you have multiple members in the structure it gets harder to work with\nsince you need to address the fields in the structure. When you work with graph,\nyou frequently need to access the vertices and in this case it felt a lot easier\nto implement the indexing in a graph, rather than explicitly access the\nunderlying data structure.

      \n

      Here you can see a rather short snippet from the solution that allows you to\n“index” the graph:

      \n
      impl Index<&str> for Graph {
      type Output = Vertex;

      fn index(&self, index: &str) -> &Self::Output {
      &self.g[index]
      }
      }
      \n

      Cartesian product

      \n

      During the implementation I had to utilize Floyd-Warshall algorithm for finding\nthe shortest path between pairs of vertices and utilized the iproduct! macro\nfrom the itertools. It is a very useful higher-order function that allows\nyou to keep the nesting of the loops at a minimum level while still maintaining\nthe same functionality.

      \n

      “Implementing” an iterator

      \n

      For the second part, you get to split the work between 2 actors. That way you\ncan achieve higher efficiency of the whole process that you're planning, but it\nalso makes it harder to evaluate algorithmically, since you need to check the\ndifferent ways the work can be split.

      \n

      Being affected by functional programming brain damage™️, I have chosen to\ndo this part by function that returns an iterator over the possible ways:

      \n
      fn pairings(
      valves: &BTreeSet<String>,
      ) -> impl Iterator<Item = (BTreeSet<String>, BTreeSet<String>)> + '_ {
      let mapping = valves.iter().collect_vec();

      let max_mask = 1 << (valves.len() - 1);

      (0..max_mask).map(move |mask| {
      let mut elephant = BTreeSet::new();
      let mut human = BTreeSet::new();

      for (i, &v) in mapping.iter().enumerate() {
      if (mask & (1 << i)) == 0 {
      human.insert(v.clone());
      } else {
      elephant.insert(v.clone());
      }
      }

      (human, elephant)
      })
      }
      \n

      Day 17: Pyroclastic Flow

      \n
      tl;dr

      Simulating an autonomous Tetris where pieces get affected by a series of jets of\nhot gas.

      \n

      Solution

      \n

      Similarly to the previous day I have created some iterators 😄

      \n

      Collision detection

      \n

      Once you need to check for collisions it is very helpful to be able to just\niterate through the positions that can actually collide with the wall or other\npiece.

      \n

      To get the desired behaviour, you can just compose few smaller functions:

      \n
      fn occupied(shape: &[Vec<char>]) -> impl Iterator<Item = Position> + '_ {
      shape.iter().enumerate().flat_map(|(y, row)| {
      row.iter().enumerate().filter_map(move |(x, c)| {
      if c == &'#' {
      Some(Vector2D::new(x as isize, y as isize))
      } else {
      None
      }
      })
      })
      }
      \n

      In the end, we get relative positions which we can adjust later when given the\nspecific positions from iterator. You can see some interesting parts in this:

      \n
        \n
      • .enumerate() allows us to get both the indices (coordinates) and the line\nor, later on, the character itself,
      • \n
      • .flat_map() flattens the iterator, i.e. when we return another iterator,\nthey just get chained instead of iterating over iterators (which sounds pretty\ndisturbing, doesn't it?),
      • \n
      • and finally .filter_map() which is pretty similar to the “basic” .map()\nwith a one, key, difference that it expects the items of an iterator to be\nmapped to an Option<T> from which it ignores nothing (as in None 😉)\nand also unwraps the values from Some(…).
      • \n
      \n

      Infinite iterator

      \n

      In the solution we cycle through both Tetris-like shapes that fall down and the\njets that move our pieces around. Initially I have implemented my own infinite\niterator that just yields the indices. It is a very simple, yet powerful, piece\nof code:

      \n
      struct InfiniteIndex {
      size: usize,
      i: usize,
      }

      impl InfiniteIndex {
      fn new(size: usize) -> InfiniteIndex {
      InfiniteIndex { size, i: size - 1 }
      }
      }

      impl Iterator for InfiniteIndex {
      type Item = usize;

      fn next(&mut self) -> Option<Self::Item> {
      self.i = (self.i + 1) % self.size;
      Some(self.i)
      }
      }
      \n

      However when I'm looking at the code now, it doesn't really make much sense…\nGuess what, we can use a built-in function that is implemented on iterators for\nthat! The function is called .cycle()

      \n

      On the other hand, I am not going to switch to that function, since it would\nintroduce an another myriad of issues caused by the fact that I create iterators\nright away in the constructor of my structure and the iterators would borrow\nboth the jets and shapes which would introduce a lifetime dependency into the\nstructure.

      \n

      Day 18: Boiling Boulders

      \n
      tl;dr

      Let's compute a surface area of some obsidian approximated via coordinates of\ncubes.

      \n

      Solution

      \n

      This day is kinda interesting, because it shows how easily you can complicate the\nproblem and also how much can you screw yourself over with the optimization and\n“smart” approach.

      \n

      For the first part you need to find the surface area of an obsidian that is\napproximated by cubes. Now, that is a very easy thing to do, just keep the track\nof already added cubes, and check if the newly added cube touches any face of any\nother cube. Simple, and with a BTreeSet relatively efficient way to do it.

      \n

      However the second part lets you on a secret that there may be some surface area\nfrom the “inside” too and you want to know only the one from the outside of the\nobsidian. I have seen some solutions later, but if you check your data, you might\nnotice that the bounding box of all the cubes isn't that big at all. Therefore I\nchose to pre-construct the box beforehand, fill in the cubes and then just run a\nBFS turning all the lava on the outside into the air. Now you just need to check\ncubes and count how many of their faces touch the air.

      \n

      Day 19: Not Enough Minerals

      \n
      tl;dr

      Finding out the best strategy for building robots to collect geodes.

      \n

      Solution

      \n

      Not much interesting stuff to mention apart from the suggestion to never believe\nthat the default implementation given by derive macro is what you want, it\ndoesn't have to be. 😄

      \n

      Day 20: Grove Positioning System

      \n
      tl;dr

      Shuffling around the circular linked list to find the coordinates.

      \n

      Now, small rant for this day is in place. They've never mentioned that coordinates\ncan repeat and therefore the values are non-unique. This is something that did\nnot happen in the given sample, but was present in the user input. It took »a lot«\nto realize that this is the issue.

      \n

      Solution

      \n

      I have tried implementing a circular linked list for this… and I have failed\nmiserably. To be fair, I still have no clue why. It was “fun” to play around with\nthe Rc<RefCell<T>>. In the end I failed on wrong answer. I have also encountered\na rather interesting issue with .borrow_mut() method being used on Rc<RefCell<T>>.

      \n

      .borrow_mut()

      \n

      Consider the following snippet of the code (taken from the documentation):

      \n
      use std::cell::{RefCell, RefMut};
      use std::collections::HashMap;
      use std::rc::Rc;
      // use std::borrow::BorrowMut;

      fn main() {
      let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
      // Create a new block to limit the scope of the dynamic borrow
      {
      let mut map: RefMut<_> = shared_map.borrow_mut();
      map.insert(\"africa\", 92388);
      map.insert(\"kyoto\", 11837);
      map.insert(\"piccadilly\", 11826);
      map.insert(\"marbles\", 38);
      }

      // Note that if we had not let the previous borrow of the cache fall out
      // of scope then the subsequent borrow would cause a dynamic thread panic.
      // This is the major hazard of using `RefCell`.
      let total: i32 = shared_map.borrow().values().sum();
      println!(\"{total}\");
      }
      \n

      We allocate a hash map on the heap and then in the inner block, we borrow it as\na mutable reference, so that we can use it.

      \n
      note

      It is a very primitive example for Rc<RefCell<T>> and mutable borrow.

      \n

      If you uncomment the 4th line with use std::borrow::BorrowMut;, you cannot\ncompile the code anymore, because of

      \n
         Compiling playground v0.0.1 (/playground)
      error[E0308]: mismatched types
      --> src/main.rs:10:34
      |
      10 | let mut map: RefMut<_> = shared_map.borrow_mut();
      | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference
      | |
      | expected due to this
      |
      = note: expected struct `RefMut<'_, _>`
      found mutable reference `&mut Rc<RefCell<HashMap<_, _>>>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:11:13
      |
      11 | map.insert(\"africa\", 92388);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:12:13
      |
      12 | map.insert(\"kyoto\", 11837);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:13:13
      |
      13 | map.insert(\"piccadilly\", 11826);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:14:13
      |
      14 | map.insert(\"marbles\", 38);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      Some errors have detailed explanations: E0308, E0599.
      For more information about an error, try `rustc --explain E0308`.
      error: could not compile `playground` due to 5 previous errors
      \n

      It might seem a bit ridiculous. However, I got to a point where the compiler\nsuggested use std::borrow::BorrowMut; and it resulted in breaking parts of the\ncode that worked previously. I think it may be a good idea to go over what is\nhappening here.

      \n
      .borrow_mut() on Rc<RefCell<T>>
      \n

      Let's consider a variable x of type Rc<RefCell<T>>. What happens when you\ncall .borrow_mut() on it? We can look at the Rc type, and… hang on! There is\nneither .borrow_mut() method or BorrowMut trait implemented. How can we do it\nthen?

      \n

      Let's go further and we can see that RefCell<T> implements a .borrow_mut()\nmethod. OK, but how can we call it on the Rc<T>? Easily! Rc<T> implements\nDeref<T> and therefore you can call methods on Rc<T> objects as if they were\nT objects. If we read on Deref coercion, we can see the following:

      \n
      \n

      If T implements Deref<Target = U>, …:

      \n
        \n
      • \n
      • T implicitly implements all the (immutable) methods of the type U.
      • \n
      \n
      \n

      What is the requirement for the .borrow_mut() on RefCell<T>? Well, it needs\n&self, so the Deref implements the .borrow_mut() for the Rc<RefCell<T>>.

      \n
      BorrowMut trait
      \n

      I have not been able to find a lot on this trait. My guess is that it provides a\nmethod instead of a syntactic sugar (&mut x) for the mutable borrow. And also\nit provides default implementations for the types:

      \n
      impl BorrowMut<str> for String

      impl<T> BorrowMut<T> for &mut T
      where
      T: ?Sized,

      impl<T> BorrowMut<T> for T
      where
      T: ?Sized,

      impl<T, A> BorrowMut<[T]> for Vec<T, A>
      where
      A: Allocator,

      impl<T, A> BorrowMut<T> for Box<T, A>
      where
      A: Allocator,
      T: ?Sized,

      impl<T, const N: usize> BorrowMut<[T]> for [T; N]
      \n
      Conflict
      \n

      Now the question is why did it break the code… My first take was that the type\nRc<RefCell<T>> has some specialized implementation of the .borrow_mut() and\nthe use overrides it with the default, which is true in a sense. However\nthere is no specialized implementation. Let's have a look at the trait and the\ntype signature on the RefCell<T>:

      \n
      // trait
      pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
      where
      Borrowed: ?Sized,
      {
      fn borrow_mut(&mut self) -> &mut Borrowed;
      }

      // ‹RefCell<T>.borrow_mut()› type signature
      pub fn borrow_mut(&self) -> RefMut<'_, T>
      \n

      I think that we can definitely agree on the fact that RefMut<'_, T> is not the\nRefCell<T>.

      \n

      In my opinion, RefCell<T> implements a separate .borrow_mut() rather\nthan implementing the interface, because it cannot satisfy the type requirements\nof the trait.

      \n
      caution

      I wonder how are we expected to deal with this conflict, if and when, we need\nboth the .borrow_mut() of the trait and .borrow_mut() of the RefCell<T>.

      \n
      Fun fact

      I was suggested by the compiler to do use std::borrow::BorrowMut; and break the\ncode.

      So much for the almighty and helpful compiler…

      \n

      Day 21: Monkey Math

      \n
      tl;dr

      Computing an expression tree and then also finding ideal value for a node.

      \n

      Solution

      \n

      Relatively simple, until you get to the 2nd part where you start to practice\na lot of the copy-paste. I have managed to sneak some perverted stuff in there\nthough :) Let's go through the details.

      \n

      Default trait

      \n

      For the first time and twice I had a need to have a default value for my types,\nenumerations in this case. Rust offers a very nice trait1 that is described\nas:

      \n
      \n

      A trait for giving a type a useful default value.

      \n
      \n

      I guess it sums it up nicely. The more interesting part about this is the fact\nthat you can use the macro machinery to save yourself some typing. If you have\nenumeration of which the default value doesn't bear any parameter, you can just\ndo2:

      \n
      #[derive(Default)]
      enum Color {
      #[default]
      White,
      Gray,
      Black,
      }
      \n

      Abusing negation

      \n

      If you want to use a unary minus operator on your own type, you can implement\na Neg trait3. I was dealing with a binary tree and needed a way how to look\nat the other side, so I have just implemented the negation for flipping between\nleft and right 😄

      \n

      Footnotes

      \n
        \n
      1. \n

        Default docs

        \n
      2. \n
      3. \n

        Pardon my example from the graph algorithms ;)

        \n
      4. \n
      5. \n

        Neg docs

        \n
      6. \n
      \n
      ", "url": "https://blog.mfocko.xyz/blog/aoc-2022/3rd-week", "title": "3rd week of Advent of Code '22 in Rust", "summary": "Surviving third week in Rust.", @@ -77,7 +77,7 @@ }, { "id": "https://blog.mfocko.xyz/blog/leetcode/sort-diagonally", - "content_html": "

      Let's try to solve one of the LeetCode challenges in easy and hard mode at the\nsame time.

      \n\n

      Problem description

      \n

      A matrix diagonal is a diagonal line of cells starting from some cell in\neither the topmost row or leftmost column and going in the bottom-right direction\nuntil reaching the matrix's end. For example, the matrix diagonal starting\nfrom mat[2][0], where mat is a 6 x 3 matrix, includes cells mat[2][0],\nmat[3][1], and mat[4][2].

      \n

      Given an m x n matrix mat of integers, sort each matrix diagonal in ascending\norder and return the resulting matrix.

      \n

      Example

      \n

      \"Image

      \n

      Skeleton and initial adjustments

      \n

      We are given the following skeleton for the C++ and the given challenge:

      \n
      class Solution {
      public:
      vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {

      }
      };
      \n

      The task is to sort the passed matrix diagonally and then return it. First of all,\nI don't like to solve this in a web browser, so we'll need to adjust it accordingly\nfor running it locally. We'll start by including the vector header and using\nfully-qualified namespaces1 and also adding few tests:

      \n
      #include <cassert>
      #include <vector>

      using matrix = std::vector<std::vector<int>>;

      class Solution {
      public:
      matrix diagonalSort(matrix& mat)
      {
      }
      };

      static void test_case_1()
      {
      // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
      // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
      std::vector { 2, 2, 1, 2 },
      std::vector { 1, 1, 1, 2 } })
      == std::vector { std::vector { 1, 1, 1, 1 },
      std::vector { 1, 2, 2, 2 },
      std::vector { 1, 2, 3, 3 } }));
      }

      static void test_case_2()
      {
      // Input: mat =
      // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
      // Output:
      // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
      std::vector { 23, 55, 17, 45, 15, 52 },
      std::vector { 75, 31, 36, 44, 58, 8 },
      std::vector { 22, 27, 33, 25, 68, 4 },
      std::vector { 84, 28, 14, 11, 5, 50 } })
      == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
      std::vector { 11, 11, 25, 45, 8, 69 },
      std::vector { 14, 23, 25, 44, 58, 15 },
      std::vector { 22, 27, 31, 36, 50, 66 },
      std::vector { 84, 28, 75, 33, 55, 68 } }));
      }

      int main()
      {
      test_case_1();
      test_case_2();

      return 0;
      }
      \n

      We need to return the matrix, but we're given a reference to the input matrix. We\ncan easily abuse the C++ here and just switch the reference to value, this way\nthe matrix will be copied when passed to the function, we can sort the copy and\njust return it back. And we also get yelled by the compiler for the fact that the\nmethod doesn't return anything yet, so to make it “shut up” we will just return\nthe input for now:

      \n
      -    matrix diagonalSort(matrix& mat)
      + matrix diagonalSort(matrix mat)
      {
      + return mat;
      }
      \n

      Now, we get the copy and we're good to go.

      \n

      Naïve solution

      \n

      As you may know, C++ offers a plethora of functions that can be used to your\nadvantage, given that you know how to “bend” the data structures accordingly.

      \n

      What does that mean for us? Well, we have an std::sort, we can use it, right?\nLet's have a look at it:

      \n
      template< class RandomIt >
      void sort( RandomIt first, RandomIt last );
      \n

      This overload is more than we need. What does it do? It just sorts the elements\nin the range [first, last) using operator< on them. We can't sort the whole\nmatrix using this, but… we can sort just »one« diagonal without doing much work\non our end.

      \n

      What is the RandomIt type though? If we look more into the documentation, we\ncan easily find the requirements for it and also learn that it's a random access\niterator and allows swapping its values at the same time.

      \n
      Random access iterator

      What is the random access iterator though? We can find it in a documentation\nand see the following description:

      \n

      A LegacyRandomAccessIterator is a LegacyBidirectionalIterator\nthat can be moved to point to any element in constant time.

      \n

      After that we can see all the requirements for it being listed. I don't feel like\nreading them right now, so we will just use it and see where the compilation blows\nup, i.e. “compiler-assisted development2 if you will ;)

      \n

      Now we know that we can use std::sort to sort the diagonal itself, but we also\nneed to get the diagonals somehow. I'm rather lazy, so I'll just delegate it to\nsomeone else3. And that way we get

      \n
      matrix diagonalSort(matrix mat)
      {
      // we iterate over the diagonals
      for (auto d : diagonals(mat)) {
      // and we sort each diagonal
      std::sort(d.begin(), d.end());
      }

      // we take the matrix by copy, so we can sort in-situ and return the copy
      // that we sorted
      return mat;
      }
      \n

      This solution looks very simple, doesn't it? Well, cause it is.\nLet's try compiling it:

      \n
      matrix-sort.cpp:11:23: error: use of undeclared identifier 'diagonals' [clang-diagnostic-error]
      for (auto d : diagonals(mat)) {
      ^
      Found compiler error(s).
      make: *** [makefile:14: tidy] Error 1
      \n

      OK, seems about right. We haven't implemented the diagonals yet. And based on\nwhat we've written so far, we need a function or a class diagonals that will\ngive us the diagonals we need.

      \n

      Implementing the diagonals

      \n

      Cool, so we need the function that will let us go through each and every diagonal\nin our matrix. We use the for-range loop, so whatever we get back from the\ndiagonals must support .begin() and .end(). Since I am a masochist, we will\ndo such functionality for a matrix of any type, not just the int from the challenge.

      \n

      As I said, we need to be able to

      \n
        \n
      • construct the object
      • \n
      • get the beginning
      • \n
      • get the end (the “sentinel”)
      • \n
      \n
      template <typename T>
      class diagonals {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& _matrix;

      public:
      diagonals(matrix_t& m)
      : _matrix(m)
      {
      }
      diagonals_iter begin()
      {
      /* TODO */
      }
      diagonals_iter end()
      {
      /* TODO */
      }
      };
      \n

      Now we have a diagonals that we can use to go through the diagonals. We haven't\nimplemented the core of it yet. Let's go through what we have for now.

      \n

      We have a templated class with templated T that is used as a placeholder for any\ntype we would store in the matrix. Because I'm lazy, I have defined the matrix_t\ntype that is a “shortcut” for std::vector<std::vector<T>>, so I don't have to\ntype it out all the time. Of course, we need to store the matrix, we are given,\nas a private attribute. And then just have the constructor and the 2 methods we\nneed for the for-range.

      \n

      Iterating over diagonals

      \n

      Now that we have an object that will allow us to iterate through the diagonals,\nwe need to implement the iterating itself. We need to go through all of them, so\nwe have multiple options how to do so. I have decided to start from the “main”\ndiagonal that starts at (0, 0) index and then proceed with the diagonals starting\nin the first row, followed by the rest of the diagonals in the first column.

      \n

      We need to be able to tell that we've iterated through all of them, and also we\nneed to know which diagonal is next. For that purpose we will pass the indices\nof the first cell on the diagonal. That way we can always tell how to move forward.

      \n

      We will start by updating the begin and end to reflect our choice accordingly.

      \n
      diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
      diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }
      \n

      For the begin we return the first diagonal that starts at (0, 0). And because\nwe have decided to do the diagonals in the first column at the end, the first\ndiagonal that is not a valid one is the one at (0, height). Apart from the\nindices, we also need to pass reference to the matrix itself.

      \n
      note

      You may have noticed that we also include the diagonals that have length 1,\nspecifically the ones at (0, height - 1) and (width - 1, 0). We are implementing\nan iterator that should not care about the way it's being used. Therefore, we\ndon't care about the fact they don't need to be sorted.

      \n

      Cool, let's leave the iterator itself to someone else, right?4

      \n

      Implementing the iterator over diagonals

      \n

      We can start with a simple skeleton based on the information that we pass from\nthe diagonals. Also to utilize the matrix_t and also contain implementation\ndetails hidden away, we will put this code into the diagonals class.

      \n
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }
      };
      \n

      In this case we will be implementing a “simple” forward iterator, so we don't\nneed to implement a lot. Notably it will be:

      \n
        \n
      • inequality operator (we need to know when we reach the end and have nothing to\niterate over)
      • \n
      • preincrementation operator (we need to be able to move around the iterable)
      • \n
      • dereference operator (we need to be able to retrieve the objects we iterate\nover)
      • \n
      \n
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator!=(const diagonals_iter& rhs) const
      {
      // iterators are not equal if they reference different matrices, or
      // their positions differ
      return m != rhs.m || x != rhs.x || y != rhs.y;
      }

      diagonals_iter& operator++()
      {
      if (y != 0) {
      // iterating through diagonals down the first column
      y++;
      return *this;
      }

      // iterating the diagonals along the first row
      x++;
      if (x == m.front().size()) {
      // switching to diagonals in the first column
      x = 0;
      y++;
      }

      return *this;
      }

      diagonal<T> operator*() const { return diagonal { m, x, y }; }
      };
      \n

      Let's go one-by-one. Inequality operator is rather simple, just compare iterator's\nattributes field-by-field. If you think about it, checking inequality of two 2D\nvectors may be a bit inefficient, therefore, we can swap around and check it as\na last thing.

      \n
      -        return m != rhs.m || x != rhs.x || y != rhs.y;
      + return x != rhs.x || y != rhs.y || m != rhs.m;
      \n

      Preincrementation is where the magic happens. If you have a better look, you can\nsee two branches of this operation:

      \n
        \n
      1. When y != 0 (we're iterating over the diagonals in the first column)\nIn this case, we just bump the row and we're done.
      2. \n
      3. When y == 0 (we're iterating over the diagonals in the first row)\nIn this case, we bump the column and check if we haven't gotten out of bounds,\ni.e. the end of the first row. If we get out of the bounds, we're continuing\nwith the second diagonal in the first column.
      4. \n
      \n

      Dereferencing the iterator must “yield” something. In our case it will be the\ndiagonal that we want to sort. For sorting we need just the iterators that can\nmove around said diagonal. The simplest thing, we can do, is to delegate it to\nsomething else. In our case it will be a class called diagonal.

      \n

      Implementing the diagonal itself

      \n

      After implementing the iterator over diagonals, we know that all we need to describe\na diagonal is the matrix itself and the “start” of the diagonal (row and column).\nAnd we also know that the diagonal must provide some iterators for the std::sort\nfunction. We can start with the following skeleton:

      \n
      template <typename T>
      class diagonal {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& matrix;
      std::size_t x;
      std::size_t y;

      public:
      diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
      : matrix(matrix)
      , x(x)
      , y(y)
      {
      }

      diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }

      diagonal_iter end() const
      {
      auto max_x = matrix[y].size();
      auto max_y = matrix.size();

      // we need to find the distance in which we get out of bounds (either in
      // column or row)
      auto steps = std::min(max_x - x, max_y - y);

      return diagonal_iter { matrix, x + steps, y + steps };
      }
      };
      \n

      Initialization is rather simple, we just “keep” the stuff we get, begin is the\nsimplest, we just delegate.

      \n

      In case of the end, it gets more complicated. We need to know where is the “end”\nof the diagonal. Since end should point to the first element “after” the iterable,\nwe know that it's the first position of the iterator where either y becomes\nmatrix.size() or x becomes matrix[y].size(). Also we are moving along diagonal,\nduh, therefore we can deduce the first “position” afterwards by minimal amount of\nsteps to get out of the any column or row, hence std::min(max_x - x, max_y - y).\nFinal position is then computed simply by adding the steps to the beginning of\nthe diagonal.

      \n

      Now we just need to finish the iterator for the diagonal itself and we're done.

      \n

      Implementing diagonal_iter

      \n

      This part is the hardest from all we need to do. It's because of the requirements\nof the std::sort that requires us to implement a random access iterator. I have\nbriefly described it above, and “in a nutshell” it means that we need to implement\nan iterator that can move in constant time along the diagonal in any amount of\nsteps.

      \n

      Let's go through all of the functionality that our iterator needs to support to\nbe used in std::sort. We need the usual operations like:

      \n
        \n
      • equality/inequality
      • \n
      • incrementation
      • \n
      • dereferencing
      • \n
      \n

      We will also add all the types that our iterator uses with the category of the\niterator, i.e. what interface it supports:

      \n
      class diagonal_iter {
      // we need to keep reference to the matrix itself
      matrix_t& m;

      // we need to be able to tell our current position
      std::size_t x;
      std::size_t y;

      public:
      using difference_type = std::ptrdiff_t;
      using value_type = T;
      using pointer = T*;
      using reference = T&;
      using iterator_category = std::random_access_iterator_tag;

      diagonal_iter(matrix_t& matrix,
      std::size_t x,
      std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator==(const diagonal_iter& rhs) const
      {
      return x == rhs.x && y == rhs.y && m == rhs.m;
      }

      diagonal_iter& operator++()
      {
      // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
      // the same time
      x++;
      y++;
      return *this;
      }

      reference operator*() const { return m[y][x]; }
      };
      \n

      This is pretty similar to the previous iterator, but now we need to implement the\nremaining requirements of the random access iterator. Let's see what those are:

      \n
        \n
      • decrementation - cause we need to be able to move backwards too, since _random _\naccess iterator extends the interface of bidirectional iterator
      • \n
      • moving the iterator in either direction by steps given as an integer
      • \n
      • being able to tell the distance between two iterators
      • \n
      • define an ordering on the iterators
      • \n
      \n

      Let's fill them in:

      \n
      class diagonal_iter {
      // we need to keep reference to the matrix itself
      matrix_t& m;

      // we need to be able to tell our current position
      std::size_t x;
      std::size_t y;

      public:
      using difference_type = std::ptrdiff_t;
      using value_type = T;
      using pointer = T*;
      using reference = T&;
      using iterator_category = std::random_access_iterator_tag;

      diagonal_iter(matrix_t& matrix,
      std::size_t x,
      std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator==(const diagonal_iter& rhs) const
      {
      return x == rhs.x && y == rhs.y && m == rhs.m;
      }

      diagonal_iter& operator++()
      {
      // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
      // the same time
      x++;
      y++;
      return *this;
      }

      reference operator*() const { return m[y][x]; }

      // exactly opposite to the incrementation
      diagonal_iter operator--()
      {
      x--;
      y--;
      return *this;
      }

      // moving ‹n› steps back is same as calling decrementation ‹n›-times, so we
      // can just return a new iterator and subtract ‹n› from both coordinates in
      // the matrix
      diagonal_iter operator-(difference_type n) const
      {
      return diagonal_iter { m, x - n, y - n };
      }

      // here we assume that we are given two iterators on the same diagonal
      difference_type operator-(const diagonal_iter& rhs) const
      {
      assert(m == rhs.m);
      return x - rhs.x;
      }

      // counterpart of moving ‹n› steps backwards
      diagonal_iter operator+(difference_type n) const
      {
      return diagonal_iter { m, x + n, y + n };
      }

      // we compare the coordinates, and also assume that those 2 iterators are
      // lying on the same diagonal
      bool operator<(const diagonal_iter& rhs) const
      {
      assert(m == rhs.m);
      return x < rhs.x && y < rhs.y;
      }
      };
      \n

      At this point we could probably try and compile it, right? If we do so, we will\nget yelled at by a compiler for the following reasons:

      \n
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
      __last = __next;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization 'std::__unguarded_linear_insert<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>' requested here
      std::__unguarded_linear_insert(__i,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization 'std::__insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__final_insertion_sort(__first, __last, __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to '__unguarded_linear_insert' [clang-diagnostic-error]
      std::__unguarded_linear_insert(__i,
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization 'std::__unguarded_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__final_insertion_sort(__first, __last, __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal<int>::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]
      __unguarded_linear_insert(_RandomAccessIterator __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
      __last = __cut;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization 'std::__introsort_loop<diagonal<int>::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__introsort_loop(__first, __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      \n

      That's a lot of noise, isn't it? Let's focus on the important parts:

      \n
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]

      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      \n

      Ah! We have a reference in our iterator, and this prevents us from having a copy\nassignment operator (that is used “somewhere” in the sorting algorithm). Well…\nLet's just wrap it!

      \n
      # we need to keep a different type than reference
      - matrix_t& m;
      + std::reference_wrapper<matrix_t> m;

      # in comparison we need to get the reference out of the wrapper first
      - return x == rhs.x && y == rhs.y && m == rhs.m;
      + return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();

      # same when we return a reference to the “cell” in the matrix
      - reference operator*() const { return m[y][x]; }
      + reference operator*() const { return m.get()[y][x]; }

      # and finally in the assertions that we set for the “distance” and “less than”
      - assert(m == rhs.m);
      + assert(m.get() == rhs.m.get());
      \n

      We're done now! We have written an iterator over diagonals for a 2D vector. You can have a look at the final result here.

      \n

      Footnotes

      \n
        \n
      1. \n

        just because I'm used to it and don't care about your opinion ;)

        \n
      2. \n
      3. \n

        exercise at your own risk

        \n
      4. \n
      5. \n

        me in 5 minutes in fact, but don't make me scared

        \n
      6. \n
      7. \n

        me in the next section…

        \n
      8. \n
      \n
      ", + "content_html": "

      Let's try to solve one of the LeetCode challenges in easy and hard mode at the\nsame time.

      \n\n

      Problem description

      \n

      A matrix diagonal is a diagonal line of cells starting from some cell in\neither the topmost row or leftmost column and going in the bottom-right direction\nuntil reaching the matrix's end. For example, the matrix diagonal starting\nfrom mat[2][0], where mat is a 6 x 3 matrix, includes cells mat[2][0],\nmat[3][1], and mat[4][2].

      \n

      Given an m x n matrix mat of integers, sort each matrix diagonal in ascending\norder and return the resulting matrix.

      \n

      Example

      \n

      \"Image

      \n

      Skeleton and initial adjustments

      \n

      We are given the following skeleton for the C++ and the given challenge:

      \n
      class Solution {
      public:
      vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {

      }
      };
      \n

      The task is to sort the passed matrix diagonally and then return it. First of all,\nI don't like to solve this in a web browser, so we'll need to adjust it accordingly\nfor running it locally. We'll start by including the vector header and using\nfully-qualified namespaces1 and also adding few tests:

      \n
      #include <cassert>
      #include <vector>

      using matrix = std::vector<std::vector<int>>;

      class Solution {
      public:
      matrix diagonalSort(matrix& mat)
      {
      }
      };

      static void test_case_1()
      {
      // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
      // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
      std::vector { 2, 2, 1, 2 },
      std::vector { 1, 1, 1, 2 } })
      == std::vector { std::vector { 1, 1, 1, 1 },
      std::vector { 1, 2, 2, 2 },
      std::vector { 1, 2, 3, 3 } }));
      }

      static void test_case_2()
      {
      // Input: mat =
      // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
      // Output:
      // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
      std::vector { 23, 55, 17, 45, 15, 52 },
      std::vector { 75, 31, 36, 44, 58, 8 },
      std::vector { 22, 27, 33, 25, 68, 4 },
      std::vector { 84, 28, 14, 11, 5, 50 } })
      == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
      std::vector { 11, 11, 25, 45, 8, 69 },
      std::vector { 14, 23, 25, 44, 58, 15 },
      std::vector { 22, 27, 31, 36, 50, 66 },
      std::vector { 84, 28, 75, 33, 55, 68 } }));
      }

      int main()
      {
      test_case_1();
      test_case_2();

      return 0;
      }
      \n

      We need to return the matrix, but we're given a reference to the input matrix. We\ncan easily abuse the C++ here and just switch the reference to value, this way\nthe matrix will be copied when passed to the function, we can sort the copy and\njust return it back. And we also get yelled by the compiler for the fact that the\nmethod doesn't return anything yet, so to make it “shut up” we will just return\nthe input for now:

      \n
      -    matrix diagonalSort(matrix& mat)
      + matrix diagonalSort(matrix mat)
      {
      + return mat;
      }
      \n

      Now, we get the copy and we're good to go.

      \n

      Naïve solution

      \n

      As you may know, C++ offers a plethora of functions that can be used to your\nadvantage, given that you know how to “bend” the data structures accordingly.

      \n

      What does that mean for us? Well, we have an std::sort, we can use it, right?\nLet's have a look at it:

      \n
      template< class RandomIt >
      void sort( RandomIt first, RandomIt last );
      \n

      This overload is more than we need. What does it do? It just sorts the elements\nin the range [first, last) using operator< on them. We can't sort the whole\nmatrix using this, but… we can sort just »one« diagonal without doing much work\non our end.

      \n

      What is the RandomIt type though? If we look more into the documentation, we\ncan easily find the requirements for it and also learn that it's a random access\niterator and allows swapping its values at the same time.

      \n
      Random access iterator

      What is the random access iterator though? We can find it in a documentation\nand see the following description:

      \n

      A LegacyRandomAccessIterator is a LegacyBidirectionalIterator\nthat can be moved to point to any element in constant time.

      \n

      After that we can see all the requirements for it being listed. I don't feel like\nreading them right now, so we will just use it and see where the compilation blows\nup, i.e. “compiler-assisted development2 if you will ;)

      \n

      Now we know that we can use std::sort to sort the diagonal itself, but we also\nneed to get the diagonals somehow. I'm rather lazy, so I'll just delegate it to\nsomeone else3. And that way we get

      \n
      matrix diagonalSort(matrix mat)
      {
      // we iterate over the diagonals
      for (auto d : diagonals(mat)) {
      // and we sort each diagonal
      std::sort(d.begin(), d.end());
      }

      // we take the matrix by copy, so we can sort in-situ and return the copy
      // that we sorted
      return mat;
      }
      \n

      This solution looks very simple, doesn't it? Well, cause it is.\nLet's try compiling it:

      \n
      matrix-sort.cpp:11:23: error: use of undeclared identifier 'diagonals' [clang-diagnostic-error]
      for (auto d : diagonals(mat)) {
      ^
      Found compiler error(s).
      make: *** [makefile:14: tidy] Error 1
      \n

      OK, seems about right. We haven't implemented the diagonals yet. And based on\nwhat we've written so far, we need a function or a class diagonals that will\ngive us the diagonals we need.

      \n

      Implementing the diagonals

      \n

      Cool, so we need the function that will let us go through each and every diagonal\nin our matrix. We use the for-range loop, so whatever we get back from the\ndiagonals must support .begin() and .end(). Since I am a masochist, we will\ndo such functionality for a matrix of any type, not just the int from the challenge.

      \n

      As I said, we need to be able to

      \n
        \n
      • construct the object
      • \n
      • get the beginning
      • \n
      • get the end (the “sentinel”)
      • \n
      \n
      template <typename T>
      class diagonals {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& _matrix;

      public:
      diagonals(matrix_t& m)
      : _matrix(m)
      {
      }
      diagonals_iter begin()
      {
      /* TODO */
      }
      diagonals_iter end()
      {
      /* TODO */
      }
      };
      \n

      Now we have a diagonals that we can use to go through the diagonals. We haven't\nimplemented the core of it yet. Let's go through what we have for now.

      \n

      We have a templated class with templated T that is used as a placeholder for any\ntype we would store in the matrix. Because I'm lazy, I have defined the matrix_t\ntype that is a “shortcut” for std::vector<std::vector<T>>, so I don't have to\ntype it out all the time. Of course, we need to store the matrix, we are given,\nas a private attribute. And then just have the constructor and the 2 methods we\nneed for the for-range.

      \n

      Iterating over diagonals

      \n

      Now that we have an object that will allow us to iterate through the diagonals,\nwe need to implement the iterating itself. We need to go through all of them, so\nwe have multiple options how to do so. I have decided to start from the “main”\ndiagonal that starts at (0, 0) index and then proceed with the diagonals starting\nin the first row, followed by the rest of the diagonals in the first column.

      \n

      We need to be able to tell that we've iterated through all of them, and also we\nneed to know which diagonal is next. For that purpose we will pass the indices\nof the first cell on the diagonal. That way we can always tell how to move forward.

      \n

      We will start by updating the begin and end to reflect our choice accordingly.

      \n
      diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
      diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }
      \n

      For the begin we return the first diagonal that starts at (0, 0). And because\nwe have decided to do the diagonals in the first column at the end, the first\ndiagonal that is not a valid one is the one at (0, height). Apart from the\nindices, we also need to pass reference to the matrix itself.

      \n
      note

      You may have noticed that we also include the diagonals that have length 1,\nspecifically the ones at (0, height - 1) and (width - 1, 0). We are implementing\nan iterator that should not care about the way it's being used. Therefore, we\ndon't care about the fact they don't need to be sorted.

      \n

      Cool, let's leave the iterator itself to someone else, right?4

      \n

      Implementing the iterator over diagonals

      \n

      We can start with a simple skeleton based on the information that we pass from\nthe diagonals. Also to utilize the matrix_t and also contain implementation\ndetails hidden away, we will put this code into the diagonals class.

      \n
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }
      };
      \n

      In this case we will be implementing a “simple” forward iterator, so we don't\nneed to implement a lot. Notably it will be:

      \n
        \n
      • inequality operator (we need to know when we reach the end and have nothing to\niterate over)
      • \n
      • preincrementation operator (we need to be able to move around the iterable)
      • \n
      • dereference operator (we need to be able to retrieve the objects we iterate\nover)
      • \n
      \n
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator!=(const diagonals_iter& rhs) const
      {
      // iterators are not equal if they reference different matrices, or
      // their positions differ
      return m != rhs.m || x != rhs.x || y != rhs.y;
      }

      diagonals_iter& operator++()
      {
      if (y != 0) {
      // iterating through diagonals down the first column
      y++;
      return *this;
      }

      // iterating the diagonals along the first row
      x++;
      if (x == m.front().size()) {
      // switching to diagonals in the first column
      x = 0;
      y++;
      }

      return *this;
      }

      diagonal<T> operator*() const { return diagonal { m, x, y }; }
      };
      \n

      Let's go one-by-one. Inequality operator is rather simple, just compare iterator's\nattributes field-by-field. If you think about it, checking inequality of two 2D\nvectors may be a bit inefficient, therefore, we can swap around and check it as\na last thing.

      \n
      -        return m != rhs.m || x != rhs.x || y != rhs.y;
      + return x != rhs.x || y != rhs.y || m != rhs.m;
      \n

      Preincrementation is where the magic happens. If you have a better look, you can\nsee two branches of this operation:

      \n
        \n
      1. When y != 0 (we're iterating over the diagonals in the first column)\nIn this case, we just bump the row and we're done.
      2. \n
      3. When y == 0 (we're iterating over the diagonals in the first row)\nIn this case, we bump the column and check if we haven't gotten out of bounds,\ni.e. the end of the first row. If we get out of the bounds, we're continuing\nwith the second diagonal in the first column.
      4. \n
      \n

      Dereferencing the iterator must “yield” something. In our case it will be the\ndiagonal that we want to sort. For sorting we need just the iterators that can\nmove around said diagonal. The simplest thing, we can do, is to delegate it to\nsomething else. In our case it will be a class called diagonal.

      \n

      Implementing the diagonal itself

      \n

      After implementing the iterator over diagonals, we know that all we need to describe\na diagonal is the matrix itself and the “start” of the diagonal (row and column).\nAnd we also know that the diagonal must provide some iterators for the std::sort\nfunction. We can start with the following skeleton:

      \n
      template <typename T>
      class diagonal {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& matrix;
      std::size_t x;
      std::size_t y;

      public:
      diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
      : matrix(matrix)
      , x(x)
      , y(y)
      {
      }

      diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }

      diagonal_iter end() const
      {
      auto max_x = matrix[y].size();
      auto max_y = matrix.size();

      // we need to find the distance in which we get out of bounds (either in
      // column or row)
      auto steps = std::min(max_x - x, max_y - y);

      return diagonal_iter { matrix, x + steps, y + steps };
      }
      };
      \n

      Initialization is rather simple, we just “keep” the stuff we get, begin is the\nsimplest, we just delegate.

      \n

      In case of the end, it gets more complicated. We need to know where is the “end”\nof the diagonal. Since end should point to the first element “after” the iterable,\nwe know that it's the first position of the iterator where either y becomes\nmatrix.size() or x becomes matrix[y].size(). Also we are moving along diagonal,\nduh, therefore we can deduce the first “position” afterwards by minimal amount of\nsteps to get out of the any column or row, hence std::min(max_x - x, max_y - y).\nFinal position is then computed simply by adding the steps to the beginning of\nthe diagonal.

      \n

      Now we just need to finish the iterator for the diagonal itself and we're done.

      \n

      Implementing diagonal_iter

      \n

      This part is the hardest from all we need to do. It's because of the requirements\nof the std::sort that requires us to implement a random access iterator. I have\nbriefly described it above, and “in a nutshell” it means that we need to implement\nan iterator that can move in constant time along the diagonal in any amount of\nsteps.

      \n

      Let's go through all of the functionality that our iterator needs to support to\nbe used in std::sort. We need the usual operations like:

      \n
        \n
      • equality/inequality
      • \n
      • incrementation
      • \n
      • dereferencing
      • \n
      \n

      We will also add all the types that our iterator uses with the category of the\niterator, i.e. what interface it supports:

      \n
      class diagonal_iter {
      // we need to keep reference to the matrix itself
      matrix_t& m;

      // we need to be able to tell our current position
      std::size_t x;
      std::size_t y;

      public:
      using difference_type = std::ptrdiff_t;
      using value_type = T;
      using pointer = T*;
      using reference = T&;
      using iterator_category = std::random_access_iterator_tag;

      diagonal_iter(matrix_t& matrix,
      std::size_t x,
      std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator==(const diagonal_iter& rhs) const
      {
      return x == rhs.x && y == rhs.y && m == rhs.m;
      }

      diagonal_iter& operator++()
      {
      // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
      // the same time
      x++;
      y++;
      return *this;
      }

      reference operator*() const { return m[y][x]; }
      };
      \n

      This is pretty similar to the previous iterator, but now we need to implement the\nremaining requirements of the random access iterator. Let's see what those are:

      \n
        \n
      • decrementation - cause we need to be able to move backwards too, since _random _\naccess iterator extends the interface of bidirectional iterator
      • \n
      • moving the iterator in either direction by steps given as an integer
      • \n
      • being able to tell the distance between two iterators
      • \n
      • define an ordering on the iterators
      • \n
      \n

      Let's fill them in:

      \n
      class diagonal_iter {
      // we need to keep reference to the matrix itself
      matrix_t& m;

      // we need to be able to tell our current position
      std::size_t x;
      std::size_t y;

      public:
      using difference_type = std::ptrdiff_t;
      using value_type = T;
      using pointer = T*;
      using reference = T&;
      using iterator_category = std::random_access_iterator_tag;

      diagonal_iter(matrix_t& matrix,
      std::size_t x,
      std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator==(const diagonal_iter& rhs) const
      {
      return x == rhs.x && y == rhs.y && m == rhs.m;
      }

      diagonal_iter& operator++()
      {
      // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
      // the same time
      x++;
      y++;
      return *this;
      }

      reference operator*() const { return m[y][x]; }

      // exactly opposite to the incrementation
      diagonal_iter operator--()
      {
      x--;
      y--;
      return *this;
      }

      // moving ‹n› steps back is same as calling decrementation ‹n›-times, so we
      // can just return a new iterator and subtract ‹n› from both coordinates in
      // the matrix
      diagonal_iter operator-(difference_type n) const
      {
      return diagonal_iter { m, x - n, y - n };
      }

      // here we assume that we are given two iterators on the same diagonal
      difference_type operator-(const diagonal_iter& rhs) const
      {
      assert(m == rhs.m);
      return x - rhs.x;
      }

      // counterpart of moving ‹n› steps backwards
      diagonal_iter operator+(difference_type n) const
      {
      return diagonal_iter { m, x + n, y + n };
      }

      // we compare the coordinates, and also assume that those 2 iterators are
      // lying on the same diagonal
      bool operator<(const diagonal_iter& rhs) const
      {
      assert(m == rhs.m);
      return x < rhs.x && y < rhs.y;
      }
      };
      \n

      At this point we could probably try and compile it, right? If we do so, we will\nget yelled at by a compiler for the following reasons:

      \n
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
      __last = __next;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization 'std::__unguarded_linear_insert<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>' requested here
      std::__unguarded_linear_insert(__i,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization 'std::__insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__final_insertion_sort(__first, __last, __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to '__unguarded_linear_insert' [clang-diagnostic-error]
      std::__unguarded_linear_insert(__i,
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization 'std::__unguarded_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__final_insertion_sort(__first, __last, __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal<int>::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]
      __unguarded_linear_insert(_RandomAccessIterator __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
      __last = __cut;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization 'std::__introsort_loop<diagonal<int>::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__introsort_loop(__first, __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      \n

      That's a lot of noise, isn't it? Let's focus on the important parts:

      \n
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]

      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      \n

      Ah! We have a reference in our iterator, and this prevents us from having a copy\nassignment operator (that is used “somewhere” in the sorting algorithm). Well…\nLet's just wrap it!

      \n
      # we need to keep a different type than reference
      - matrix_t& m;
      + std::reference_wrapper<matrix_t> m;

      # in comparison we need to get the reference out of the wrapper first
      - return x == rhs.x && y == rhs.y && m == rhs.m;
      + return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();

      # same when we return a reference to the “cell” in the matrix
      - reference operator*() const { return m[y][x]; }
      + reference operator*() const { return m.get()[y][x]; }

      # and finally in the assertions that we set for the “distance” and “less than”
      - assert(m == rhs.m);
      + assert(m.get() == rhs.m.get());
      \n

      We're done now! We have written an iterator over diagonals for a 2D vector. You can have a look at the final result here.

      \n

      Footnotes

      \n
        \n
      1. \n

        just because I'm used to it and don't care about your opinion ;)

        \n
      2. \n
      3. \n

        exercise at your own risk

        \n
      4. \n
      5. \n

        me in 5 minutes in fact, but don't make me scared

        \n
      6. \n
      7. \n

        me in the next section…

        \n
      8. \n
      \n
      ", "url": "https://blog.mfocko.xyz/blog/leetcode/sort-diagonally", "title": "Sort the matrix diagonally", "summary": "Compiler assisted development.", @@ -94,7 +94,7 @@ }, { "id": "https://blog.mfocko.xyz/blog/aoc-2022/2nd-week", - "content_html": "

      Let's go through the second week of Advent of Code in Rust.

      \n

      Day 8: Treetop Tree House

      \n
      tl;dr

      We get a forest and we want to know how many trees are visible from the outside.\nApart from that we want to find the best view.

      \n

      Nothing interesting. We are moving around 2D map though. And indexing can get a\nbit painful when doing so, let's refactor it a bit ;) During the preparation for\nthe AoC, I have written Vector2D and now it's time to extend it with indexing\nof Vec of Vecs. In my solution I was manipulating with indices in the following\nway:

      \n
        \n
      • swapping them
      • \n
      • checking whether they are correct indices for the Vec<Vec<T>>
      • \n
      • indexing Vec<Vec<T>> with them
      • \n
      \n
      caution

      I'm getting familiar with Rust and starting to “abuse” it… While doing so, I'm\nalso uncovering some “features” that I don't really like. Therefore I will mark\nall of my rants with thicc «↯» mark and will try to “lock” them into their\nown “box of hell”.

      \n

      Swapping indices

      \n

      Relatively simple implementation, just take the values, swap them and return new\nvector.

      \n
      impl<T: Copy> Vector2D<T> {
      pub fn swap(&self) -> Self {
      Self {
      x: self.y,
      y: self.x,
      }
      }
      }
      \n

      Pretty straight-forward implementation, but let's talk about the T: Copy. We\nneed to use it, since we are returning a new vector, with swapped values.\nIf we had values that cannot be copied, the only thing we could do, would be a\nvector of references (and it would also introduce a lifetime, to which we'll get\nlater on). This is pretty similar with the operations on sets from the first week.

      \n

      Indexing Vec

      \n

      I will start with the indexing, cause bound-checking is a bit more… complicated\nthan I would like to.

      \n
      pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U
      where
      usize: TryFrom<T>,
      <usize as TryFrom<T>>::Error: Debug,
      T: Copy,
      {
      let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
      &v[y][x]
      }
      \n

      Let's talk about this mess… Body of the function is probably the most easy part\nand should not be hard to understand, we just take the x and y and convert\nthem both to usize type that can be used later on for indexing.

      \n

      The type signature of the function is where the fun is at 😉 We are trying\nto convert unknown type to usize, so we must bound the T as a type that can\nbe converted to usize, that's how we got usize: TryFrom<T> which basically\nsays that usize must implement TryFrom<T> trait and therefore allows us to\nconvert the indices to actual usize indices. Using .unwrap() also forces us\nto bound the error that can occur when converting T into usize, that's how\nwe get <usize as TryFrom<T>>::Error: Debug which loosely means

      \n
      \n

      error during conversion of T into usize must implement Debug,\ni.e. can be printed in some way or other

      \n
      \n

      T: Copy is required by .try_into() which takes T by-value.

      \n

      And now we are left only with the first line of the definition.

      \n
      note

      Skilled Rustaceans might notice that this implementation is rather flaky and can\nbreak in multiple places at once. I'll get back to it…

      \n

      Let's split it in multiple parts:

      \n
        \n
      • v: &'a [Vec<U>] represents the 2D Vec, we are indexing, Vec implements\nSlice trait and clippy recommends using &[T] to &Vec<T>, exact details\nare unknown to me
      • \n
      • idx: &Vector2D<T> represents the indices which we use, we take them by\nreference to avoid an unnecessary copy
      • \n
      • -> &'a U means that we are returning a reference to some value of type U.\nNow the question is what does the 'a mean, we can also see it as a generic\ntype declared along T and U. And the answer is relatively simple, 'a\nrepresents a lifetime. We take the v by a reference and return a reference,\nborrow checker validates all of the borrows (or references), so we need to\nspecify that our returned value has the same lifetime as the vector we have\ntaken by a reference, i.e. returned reference must live at least as long as the\nv. This way we can “be sure” that the returned reference is valid.
      • \n
      \n
      Issues
      \n

      First issue that our implementation has is the fact that we cannot get a mutable\nreference out of that function. This could be easily resolved by introducing new\nfunction, e.g. index_mut. Which I have actually done while writing this part:

      \n
      pub fn index_mut<'a, T, U>(v: &'a mut [Vec<U>], idx: &Vector2D<T>) -> &'a mut U
      where
      usize: TryFrom<T>,
      <usize as TryFrom<T>>::Error: Debug,
      T: Copy,
      {
      let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
      &mut v[y][x]
      }
      \n
      «↯» Why can't we use one function?

      When we consider a Vec<T>, we don't need to consider containers as T, Rust\nimplements indexing as traits Index<T> and IndexMut<T> that do the dirty work\nbehind syntactic sugar of container[idx].

      However, implementing of traits is not allowed for external types, i.e. types\nthat you haven't defined yourself. This means that you can implement indexing\nover containers that you have implemented yourself, but you cannot use your own\ntypes for indexing “built-in” types.

      Another part of this rabbit hole is trait SliceIndex<T> that is of a relevance\nbecause of

      impl<T, I> Index<I> for [T]
      where
      I: SliceIndex<[T]>

      impl<T, I, A> Index<I> for Vec<T, A>
      where
      I: SliceIndex<[T]>,
      A: Allocator

      impl<T, I, const N: usize> Index<I> for [T; N]
      where
      [T]: Index<I>

      In other words, if your type implements SliceIndex<T> trait, it can be used\nfor indexing. As of now, this trait has all of its required methods experimental\nand is marked as unsafe.

      \n

      Another problem is a requirement for indexing either [Vec<T>] or Vec<Vec<T>>.\nThis requirement could be countered by removing inner type Vec<T> and constraining\nit by a trait Index (or IndexMut respectively) in a following way

      \n
      pub fn index<'a, C, T>(v: &'a [C], idx: &Vector2D<T>) -> &'a C::Output
      where
      usize: TryFrom<T>,
      <usize as TryFrom<T>>::Error: Debug,
      T: Copy,
      C: Index<usize>
      {
      let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
      &v[y][x]
      }
      \n

      Given this, we can also give a more meaningful typename for indexing type, such\nas I.

      \n

      Checking bounds

      \n

      Now we can get to the boundary checks, it is very similar, but a more… dirty.\nFirst approach that came up was to convert the indices in Vector2D to usize,\nbut when you add the indices up, e.g. when checking the neighbors, you can end\nup with negative values which, unlike in C++, causes an error (instead of underflow\nthat you can use to your advantage; you can easily guess how).

      \n

      So how can we approach this then? Well… we will convert the bounds instead of\nthe indices and that lead us to:

      \n
      pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
      where
      usize: TryInto<T>,
      <usize as TryInto<T>>::Error: Debug,
      T: PartialOrd + Copy,
      {
      idx.y >= 0.try_into().unwrap()
      && idx.y < v.len().try_into().unwrap()
      && idx.x >= 0.try_into().unwrap()
      && idx.x
      < v[TryInto::<usize>::try_into(idx.y).unwrap()]
      .len()
      .try_into()
      .unwrap()
      }
      \n

      You can tell that it's definitely a shitty code. Let's improve it now! We will\nget back to the original idea, but do it better. We know that we cannot convert\nnegative values into usize, but we also know that conversion like that\nreturns a Result<T, E> which we can use to our advantage.

      \n
      pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
      where
      T: Copy,
      usize: TryFrom<T>,
      {
      usize::try_from(idx.y)
      .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))
      .unwrap_or(false)
      }
      \n

      Result<T, E> is a type similar to Either in Haskell and it allows us to chain\nmultiple operations on correct results or propagate the original error without\ndoing anything. Let's dissect it one-by-one.

      \n

      try_from is a method implemented in TryFrom trait, that allows you to convert\ntypes and either successfully convert them or fail (with a reasonable error). This\nmethod returns Result<T, E>.

      \n

      We call and_then on that result, let's have a look at the type signature of\nand_then, IMO it explains more than enough:

      \n
      pub fn and_then<U, F>(self, op: F) -> Result<U, E>
      where
      F: FnOnce(T) -> Result<U, E>
      \n

      OK… So it takes the result and a function and returns another result with\ndifferent value and different error. However we can see that the function, which\nrepresents an operation on a result, takes just the value, i.e. it doesn't care\nabout any previous error. To make it short:

      \n
      \n

      and_then allows us to run an operation, which can fail, on the correct result

      \n
      \n

      We parsed a y index and now we try to convert the x index with try_from\nagain, but on that result we use map rather than and_then, why would that be?

      \n
      pub fn map<U, F>(self, op: F) -> Result<U, E>
      where
      F: FnOnce(T) -> U
      \n

      Huh… map performs an operation that cannot fail. And finally we use\nunwrap_or which takes the value from result, or in case of an error returns the\ndefault that we define.

      \n

      How does this work then? If y is negative, the conversion fails and the error\npropagates all the way to unwrap_or, if y can be a correct usize value, then\nwe do the same with x. If x is negative, we propagate the error as with y,\nand if it's not, then we check whether it exceeds the higher bounds or not.

      \n

      Solution

      \n

      Relatively simple, you just need follow the rules and not get too smart, otherwise\nit will get back at you.

      \n

      Day 9: Rope Bridge

      \n
      tl;dr

      We get a rope with knots and we want to track how many different positions are\nvisited with the rope's tail.

      \n

      By this day, I have come to a conclusion that current skeleton for each day\ngenerates a lot of boilerplate. And even though it can be easily copied, it's\njust a waste of space and unnecessary code. Let's “simplify” this (on one end\nwhile creating monster on the other end). I've gone through what we need in the\npreparations for the AoC. Let's sum up our requirements:

      \n
        \n
      • parsing
      • \n
      • part 1 & 2
      • \n
      • running on sample / input
      • \n
      • tests
      • \n
      \n

      Parsing and implementation of both parts is code that changes each day and we\ncannot do anything about it. However running and testing can be simplified!

      \n

      Let's introduce and export a new module solution that will take care of all of\nthis. We will start by introducing a trait for each day.

      \n
      pub trait Solution<Input, Output: Display> {
      fn parse_input<P: AsRef<Path>>(pathname: P) -> Input;

      fn part_1(input: &Input) -> Output;
      fn part_2(input: &Input) -> Output;
      }
      \n

      This does a lot of work for us already, we have defined a trait and for each day\nwe will create a structure representing a specific day. That structure will also\nimplement the Solution trait.

      \n

      Now we need to get rid of the boilerplate, we can't get rid of the main function,\nbut we can at least move out the functionality.

      \n
      fn run(type_of_input: &str) -> Result<()>
      where
      Self: Sized,
      {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = Self::parse_input(format!(\"{}s/{}.txt\", type_of_input, Self::day()));

      info!(\"Part 1: {}\", Self::part_1(&input));
      info!(\"Part 2: {}\", Self::part_2(&input));

      Ok(())
      }

      fn main() -> Result<()>
      where
      Self: Sized,
      {
      Self::run(\"input\")
      }
      \n

      This is all part of the Solution trait, which can implement methods while being\ndependent on what is provided by the implementing types. In this case, we just\nneed to bound the Output type to implement Display that is necessary for the\ninfo! and format string there.

      \n

      Now we can get to first of the nasty things we are going to do… And it is the\nday() method that you can see being used when constructing path to the input\nfile. That method will generate a name of the file, e.g. day01 and we know that\nwe can somehow deduce it from the structure name, given we name it reasonably.

      \n
      fn day() -> String {
      let mut day = String::from(type_name::<Self>().split(\"::\").next().unwrap());
      day.make_ascii_lowercase();

      day.to_string()
      }
      \n
      type_name

      This feature is still experimental and considered to be internal, it is not\nadvised to use it any production code.

      \n

      And now we can get to the nastiest stuff 😩 We will generate the tests!

      \n

      We want to be able to generate tests for sample input in a following way:

      \n
      test_sample!(day_01, Day01, 42, 69);
      \n

      There's not much we can do, so we will write a macro to generate the tests for us.

      \n
      #[macro_export]
      macro_rules! test_sample {
      ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {
      #[cfg(test)]
      mod $mod_name {
      use super::*;

      #[test]
      fn test_part_1() {
      let sample =
      $day_struct::parse_input(&format!(\"samples/{}.txt\", $day_struct::day()));
      assert_eq!($day_struct::part_1(&sample), $part_1);
      }

      #[test]
      fn test_part_2() {
      let sample =
      $day_struct::parse_input(&format!(\"samples/{}.txt\", $day_struct::day()));
      assert_eq!($day_struct::part_2(&sample), $part_2);
      }
      }
      };
      }
      \n

      We have used it in a similar way as macros in C/C++, one of the things that we\ncan use to our advantage is defining “type” of the parameters for the macro. All\nparameters have their name prefixed with $ sign and you can define various “forms”\nof your macro. Let's go through it!

      \n

      We have following parameters:

      \n
        \n
      • $mod_name which represents the name for the module with tests, it is typed\nwith ident which means that we want a valid identifier to be passed in.
      • \n
      • $day_struct represents the structure that will be used for tests, it is typed\nwith tt which represents a token tree, in our case it is a type.
      • \n
      • $part_X represents the expected output for the Xth part and is of type expr\nwhich literally means an expression.
      • \n
      \n

      Apart from that we need to use #[macro_export] to mark the macro as exported\nfor usage outside of the module. Now our skeleton looks like:

      \n
      use aoc_2022::*;

      type Input = String;
      type Output = String;

      struct DayXX;
      impl Solution<Input, Output> for DayXX {
      fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
      file_to_string(pathname)
      }

      fn part_1(input: &Input) -> Output {
      todo!()
      }

      fn part_2(input: &Input) -> Output {
      todo!()
      }
      }

      fn main() -> Result<()> {
      // DayXX::run(\"sample\")
      DayXX::main()
      }

      // test_sample!(day_XX, DayXX, , );
      \n

      Solution

      \n

      Not much to talk about, it is relatively easy to simulate.

      \n

      Day 10: Cathode-Ray Tube

      \n
      tl;dr

      Emulating basic arithmetic operations on a CPU and drawing on CRT based on the\nCPU's accumulator.

      \n

      In this day I have discovered an issue with my design of the Solution trait.\nAnd the issue is caused by different types of Output for the part 1 and part 2.

      \n

      Problem is relatively simple and consists of simulating a CPU, I have approached\nit in a following way:

      \n
      fn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {
      instructions
      .iter()
      .fold(State::new(), |state, instruction| {
      state.execute(instruction, &mut out)
      });

      out
      }
      \n

      We just take the instructions, we have some state of the CPU and we execute the\ninstructions one-by-one. Perfect usage of the fold (or reduce as you may know\nit from other languages).

      \n

      You can also see that we have an Output type, so the question is how can we fix\nthat problem. And the answer is very simple and functional. Rust allows you to\nhave an enumeration that can bear some other values apart from the type itself.

      \n
      tip

      We could've seen something like this with the Result<T, E> type that can be\ndefined as

      enum Result<T, E> {
      Ok(T),
      Err(E)
      }
      What does that mean though?

      When we have an Ok value, it has the result itself, and when we get an Err\nvalue, it has the error. This also allows us to handle results in a rather\npretty way:

      match do_something(x) {
      Ok(y) => {
      println!(\"SUCCESS: {}\", y);
      },
      Err(y) => {
      eprintln!(\"ERROR: {}\", y);
      }
      }
      \n

      My solution has a following outline:

      \n
      fn execute(&self, i: &Instruction, output: &mut Output) -> State {
      // execute the instruction

      // collect results if necessary
      match output {
      Output::Part1(x) => self.execute_part_1(y, x),
      Output::Part2(x) => self.execute_part_2(y, x),
      }

      // return the obtained state
      new_state
      }
      \n

      You might think that it's a perfectly reasonable thing to do. Yes, but notice\nthat the match statement doesn't collect the changes in any way and also we\npass output by &mut, so it is shared across each iteration of the fold.

      \n

      The dirty and ingenious thing is that xs are passed by &mut too and therefore\nthey are directly modified by the helper functions. To sum it up and let it sit

      \n
      \n

      We are collecting the result into an enumeration that is shared\nacross all iterations of fold.

      \n
      \n

      Solution

      \n

      Similar to Day 9, but there are some technical details that can get you.

      \n

      Day 11: Monkey in the Middle

      \n
      tl;dr

      Simulation of monkeys throwing stuff around and measuring your stress levels\nwhile your stuff is being passed around.

      \n

      I think I decided to use regular expressions here for the first time, cause\nparsing the input was a pain.

      \n

      Also I didn't expect to implement Euclidean algorithm in Rust…

      \n

      Solution

      \n

      Again, we're just running a simulation. Though I must admit it was very easy to\nmake a small technical mistakes that could affect the final results very late.

      \n

      Day 12: Hill Climbing Algorithm

      \n
      tl;dr

      Finding shortest path up the hill and also shortest path down to the ground while\nalso rolling down the hill…

      \n

      As I have said in the tl;dr, we are looking for the shortest path, but the start\nand goal differ for the part 1 and 2. So I have decided to refactor my solution\nto a BFS algorithm that takes necessary parameters via functions:

      \n
      fn bfs<F, G>(
      graph: &[Vec<char>], start: &Position, has_edge: F, is_target: G
      ) -> Option<usize>
      where
      F: Fn(&[Vec<char>], &Position, &Position) -> bool,
      G: Fn(&[Vec<char>], &Position) -> bool
      \n

      We pass the initial vertex from the caller and everything else is left to the BFS\nalgorithm, based on the has_edge and is_target functions.

      \n

      This was easy! And that is not very usual in Rust once you want to pass around\nfunctions. 👀

      \n

      Solution

      \n

      Looking for the shortest path… Must be Dijkstra, right? Nope! Half of the\nReddit got jebaited though. In all fairness, nothing stops you from implementing\nthe Dijkstra's algorithm for finding the shortest path, but if you know that\nall connected vertices are in a unit (actually d=1d = 1d=1) distance from each other,\nthen you know that running Dijkstra is equivalent to running BFS, only with worse\ntime complexity, because of the priority heap instead of the queue.

      \n

      Day 13: Distress Signal

      \n
      tl;dr

      Processing packets with structured data from the distress signal.

      \n

      You can implement a lot of traits if you want to. It is imperative to implement\nordering on the packets. I had a typo, so I also proceeded to implement a Display\ntrait for debugging purposes:

      \n
      impl Display for Packet {
      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      match self {
      Packet::Integer(x) => write!(f, \"{x}\"),
      Packet::List(lst) => write!(f, \"[{}]\", lst.iter().map(|p| format!(\"{p}\")).join(\",\")),
      }
      }
      }
      \n

      Solution

      \n

      A lot of technical details… Parsing is nasty too…

      \n

      Day 14: Regolith Reservoir

      \n
      tl;dr

      Let's simulate falling sand grain-by-grain.

      \n

      Again, both parts are relatively similar with minimal changes, so it is a good\nidea to refactor it a bit. Similar approach to the BFS above. Also this is the\nfirst day where I ran into efficiency issues and had to redo my solution to speed\nit up just a bit.

      \n

      Solution

      \n

      Tedious.

      \n

      Post Mortem

      \n

      Indexing

      \n

      I was asked about the indexing after publishing the blog. And truly it is rather\ncomplicated topic, especially after releasing SliceIndex<I> trait. I couldn't\nleave it be, so I tried to implement the Index and IndexMut trait.

      \n
      note

      I have also mentioned that the SliceIndex trait is unsafe, but truth be told,\nonly unsafe part are the 2 methods that are named *unchecked*. Anyways, I will\nbe implementing the Index* traits for now, rather than the SliceIndex.

      \n

      It's relatively straightforward…

      \n
      impl<I, C> Index<Vector2D<I>> for [C]
      where
      I: Copy + TryInto<usize>,
      <I as TryInto<usize>>::Error: Debug,
      C: Index<usize>,
      {
      type Output = C::Output;

      fn index(&self, index: Vector2D<I>) -> &Self::Output {
      let (x, y): (usize, usize) =
      (index.x.try_into().unwrap(), index.y.try_into().unwrap());
      &self[y][x]
      }
      }

      impl<I, C> IndexMut<Vector2D<I>> for [C]
      where
      I: Copy + TryInto<usize>,
      <I as TryInto<usize>>::Error: Debug,
      C: IndexMut<usize>,
      {
      fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
      let (x, y): (usize, usize) =
      (index.x.try_into().unwrap(), index.y.try_into().unwrap());
      &mut self[y][x]
      }
      }
      \n

      We can see a lot of similarities to the implementation of index and index_mut\nfunctions. In the end, they are 1:1, just wrapped in the trait that provides a\nsyntax sugar for container[idx].

      \n
      note

      I have also switched from using the TryFrom to TryInto trait, since it better\nmatches what we are using, the .try_into rather than usize::try_from.

      Also implementing TryFrom automatically provides you with a TryInto trait,\nsince it is relatively easy to implement. Just compare the following:

      pub trait TryFrom<T>: Sized {
      type Error;

      fn try_from(value: T) -> Result<Self, Self::Error>;
      }

      pub trait TryInto<T>: Sized {
      type Error;

      fn try_into(self) -> Result<T, Self::Error>;
      }
      \n

      OK, so we have our trait implemented, we should be able to use container[index],\nright? Yes… but actually no 😦

      \n
      error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
      --> src/bin/day08.rs:26:18
      |
      26 | if trees[pos] > tallest {
      | ^^^ slice indices are of type `usize` or ranges of `usize`
      |
      = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
      = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

      error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
      --> src/bin/day08.rs:30:28
      |
      30 | max(tallest, trees[pos])
      | ^^^ slice indices are of type `usize` or ranges of `usize`
      |
      = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
      = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

      error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<isize>`
      --> src/bin/day08.rs:52:28
      |
      52 | let max_height = trees[position];
      | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
      |
      = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<isize>`
      = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<isize>>`
      \n

      Why? We have it implemented for the slices ([C]), why doesn't it work? Well,\nthe fun part consists of the fact that in other place, where we were using it,\nwe were passing the &[Vec<T>], but this is coming from a helper functions that\ntake &Vec<Vec<T>> instead. And… we don't implement Index and IndexMut for\nthose. Just for the slices. 🤯 What are we going to do about it?

      \n

      We can either start copy-pasting or be smarter about it… I choose to be smarter,\nso let's implement a macro! The only difference across the implementations are\nthe types of the outer containers. Implementation doesn't differ at all!

      \n

      Implementing the macro can be done in a following way:

      \n
      macro_rules! generate_indices {
      ($container:ty) => {
      impl<I, C> Index<Vector2D<I>> for $container
      where
      I: Copy + TryInto<usize>,
      <I as TryInto<usize>>::Error: Debug,
      C: Index<usize>,
      {
      type Output = C::Output;

      fn index(&self, index: Vector2D<I>) -> &Self::Output {
      let (x, y): (usize, usize) =
      (index.x.try_into().unwrap(), index.y.try_into().unwrap());
      &self[y][x]
      }
      }

      impl<I, C> IndexMut<Vector2D<I>> for $container
      where
      I: Copy + TryInto<usize>,
      <I as TryInto<usize>>::Error: Debug,
      C: IndexMut<usize>,
      {
      fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
      let (x, y): (usize, usize) =
      (index.x.try_into().unwrap(), index.y.try_into().unwrap());
      &mut self[y][x]
      }
      }
      };
      }
      \n

      And now we can simply do

      \n
      generate_indices!(VecDeque<C>);
      generate_indices!([C]);
      generate_indices!(Vec<C>);
      // generate_indices!([C; N], const N: usize);
      \n

      The last type (I took the inspiration from the implementations of the Index and\nIndexMut traits) is a bit problematic, because of the const N: usize part,\nwhich I haven't managed to be able to parse. And that's how I got rid of the error.

      \n
      note

      If I were to use 2D-indexing over [C; N] slices, I'd probably just go with the\ncopy-paste, cause the cost of this “monstrosity” outweighs the benefits of no DRY.

      \n

      Cause of the problem

      \n

      This issue is relatively funny. If you don't use any type aliases, just the raw\ntypes, you'll get suggested certain changes by the clippy. For example if you\nconsider the following piece of code

      \n
      fn get_sum(nums: &Vec<i32>) -> i32 {
      nums.iter().sum()
      }

      fn main() {
      let nums = vec![1, 2, 3];
      println!(\"Sum: {}\", get_sum(&nums));
      }
      \n

      and you run clippy on it, you will get

      \n
      Checking playground v0.0.1 (/playground)
      warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
      --> src/main.rs:1:18
      |
      1 | fn get_sum(nums: &Vec<i32>) -> i32 {
      | ^^^^^^^^^ help: change this to: `&[i32]`
      |
      = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
      = note: `#[warn(clippy::ptr_arg)]` on by default

      warning: `playground` (bin \"playground\") generated 1 warning
      Finished dev [unoptimized + debuginfo] target(s) in 0.61s
      \n

      However, if you introduce a type alias, such as

      \n
      type Numbers = Vec<i32>;
      \n

      Then clippy won't say anything, cause there is literally nothing to suggest.\nHowever the outcome is not the same…

      ", + "content_html": "

      Let's go through the second week of Advent of Code in Rust.

      \n

      Day 8: Treetop Tree House

      \n
      tl;dr

      We get a forest and we want to know how many trees are visible from the outside.\nApart from that we want to find the best view.

      \n

      Nothing interesting. We are moving around 2D map though. And indexing can get a\nbit painful when doing so, let's refactor it a bit ;) During the preparation for\nthe AoC, I have written Vector2D and now it's time to extend it with indexing\nof Vec of Vecs. In my solution I was manipulating with indices in the following\nway:

      \n
        \n
      • swapping them
      • \n
      • checking whether they are correct indices for the Vec<Vec<T>>
      • \n
      • indexing Vec<Vec<T>> with them
      • \n
      \n
      caution

      I'm getting familiar with Rust and starting to “abuse” it… While doing so, I'm\nalso uncovering some “features” that I don't really like. Therefore I will mark\nall of my rants with thicc «↯» mark and will try to “lock” them into their\nown “box of hell”.

      \n

      Swapping indices

      \n

      Relatively simple implementation, just take the values, swap them and return new\nvector.

      \n
      impl<T: Copy> Vector2D<T> {
      pub fn swap(&self) -> Self {
      Self {
      x: self.y,
      y: self.x,
      }
      }
      }
      \n

      Pretty straight-forward implementation, but let's talk about the T: Copy. We\nneed to use it, since we are returning a new vector, with swapped values.\nIf we had values that cannot be copied, the only thing we could do, would be a\nvector of references (and it would also introduce a lifetime, to which we'll get\nlater on). This is pretty similar with the operations on sets from the first week.

      \n

      Indexing Vec

      \n

      I will start with the indexing, cause bound-checking is a bit more… complicated\nthan I would like to.

      \n
      pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U
      where
      usize: TryFrom<T>,
      <usize as TryFrom<T>>::Error: Debug,
      T: Copy,
      {
      let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
      &v[y][x]
      }
      \n

      Let's talk about this mess… Body of the function is probably the most easy part\nand should not be hard to understand, we just take the x and y and convert\nthem both to usize type that can be used later on for indexing.

      \n

      The type signature of the function is where the fun is at 😉 We are trying\nto convert unknown type to usize, so we must bound the T as a type that can\nbe converted to usize, that's how we got usize: TryFrom<T> which basically\nsays that usize must implement TryFrom<T> trait and therefore allows us to\nconvert the indices to actual usize indices. Using .unwrap() also forces us\nto bound the error that can occur when converting T into usize, that's how\nwe get <usize as TryFrom<T>>::Error: Debug which loosely means

      \n
      \n

      error during conversion of T into usize must implement Debug,\ni.e. can be printed in some way or other

      \n
      \n

      T: Copy is required by .try_into() which takes T by-value.

      \n

      And now we are left only with the first line of the definition.

      \n
      note

      Skilled Rustaceans might notice that this implementation is rather flaky and can\nbreak in multiple places at once. I'll get back to it…

      \n

      Let's split it in multiple parts:

      \n
        \n
      • v: &'a [Vec<U>] represents the 2D Vec, we are indexing, Vec implements\nSlice trait and clippy recommends using &[T] to &Vec<T>, exact details\nare unknown to me
      • \n
      • idx: &Vector2D<T> represents the indices which we use, we take them by\nreference to avoid an unnecessary copy
      • \n
      • -> &'a U means that we are returning a reference to some value of type U.\nNow the question is what does the 'a mean, we can also see it as a generic\ntype declared along T and U. And the answer is relatively simple, 'a\nrepresents a lifetime. We take the v by a reference and return a reference,\nborrow checker validates all of the borrows (or references), so we need to\nspecify that our returned value has the same lifetime as the vector we have\ntaken by a reference, i.e. returned reference must live at least as long as the\nv. This way we can “be sure” that the returned reference is valid.
      • \n
      \n
      Issues
      \n

      First issue that our implementation has is the fact that we cannot get a mutable\nreference out of that function. This could be easily resolved by introducing new\nfunction, e.g. index_mut. Which I have actually done while writing this part:

      \n
      pub fn index_mut<'a, T, U>(v: &'a mut [Vec<U>], idx: &Vector2D<T>) -> &'a mut U
      where
      usize: TryFrom<T>,
      <usize as TryFrom<T>>::Error: Debug,
      T: Copy,
      {
      let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
      &mut v[y][x]
      }
      \n
      «↯» Why can't we use one function?

      When we consider a Vec<T>, we don't need to consider containers as T, Rust\nimplements indexing as traits Index<T> and IndexMut<T> that do the dirty work\nbehind syntactic sugar of container[idx].

      However, implementing of traits is not allowed for external types, i.e. types\nthat you haven't defined yourself. This means that you can implement indexing\nover containers that you have implemented yourself, but you cannot use your own\ntypes for indexing “built-in” types.

      Another part of this rabbit hole is trait SliceIndex<T> that is of a relevance\nbecause of

      impl<T, I> Index<I> for [T]
      where
      I: SliceIndex<[T]>

      impl<T, I, A> Index<I> for Vec<T, A>
      where
      I: SliceIndex<[T]>,
      A: Allocator

      impl<T, I, const N: usize> Index<I> for [T; N]
      where
      [T]: Index<I>

      In other words, if your type implements SliceIndex<T> trait, it can be used\nfor indexing. As of now, this trait has all of its required methods experimental\nand is marked as unsafe.

      \n

      Another problem is a requirement for indexing either [Vec<T>] or Vec<Vec<T>>.\nThis requirement could be countered by removing inner type Vec<T> and constraining\nit by a trait Index (or IndexMut respectively) in a following way

      \n
      pub fn index<'a, C, T>(v: &'a [C], idx: &Vector2D<T>) -> &'a C::Output
      where
      usize: TryFrom<T>,
      <usize as TryFrom<T>>::Error: Debug,
      T: Copy,
      C: Index<usize>
      {
      let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
      &v[y][x]
      }
      \n

      Given this, we can also give a more meaningful typename for indexing type, such\nas I.

      \n

      Checking bounds

      \n

      Now we can get to the boundary checks, it is very similar, but a more… dirty.\nFirst approach that came up was to convert the indices in Vector2D to usize,\nbut when you add the indices up, e.g. when checking the neighbors, you can end\nup with negative values which, unlike in C++, causes an error (instead of underflow\nthat you can use to your advantage; you can easily guess how).

      \n

      So how can we approach this then? Well… we will convert the bounds instead of\nthe indices and that lead us to:

      \n
      pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
      where
      usize: TryInto<T>,
      <usize as TryInto<T>>::Error: Debug,
      T: PartialOrd + Copy,
      {
      idx.y >= 0.try_into().unwrap()
      && idx.y < v.len().try_into().unwrap()
      && idx.x >= 0.try_into().unwrap()
      && idx.x
      < v[TryInto::<usize>::try_into(idx.y).unwrap()]
      .len()
      .try_into()
      .unwrap()
      }
      \n

      You can tell that it's definitely a shitty code. Let's improve it now! We will\nget back to the original idea, but do it better. We know that we cannot convert\nnegative values into usize, but we also know that conversion like that\nreturns a Result<T, E> which we can use to our advantage.

      \n
      pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
      where
      T: Copy,
      usize: TryFrom<T>,
      {
      usize::try_from(idx.y)
      .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))
      .unwrap_or(false)
      }
      \n

      Result<T, E> is a type similar to Either in Haskell and it allows us to chain\nmultiple operations on correct results or propagate the original error without\ndoing anything. Let's dissect it one-by-one.

      \n

      try_from is a method implemented in TryFrom trait, that allows you to convert\ntypes and either successfully convert them or fail (with a reasonable error). This\nmethod returns Result<T, E>.

      \n

      We call and_then on that result, let's have a look at the type signature of\nand_then, IMO it explains more than enough:

      \n
      pub fn and_then<U, F>(self, op: F) -> Result<U, E>
      where
      F: FnOnce(T) -> Result<U, E>
      \n

      OK… So it takes the result and a function and returns another result with\ndifferent value and different error. However we can see that the function, which\nrepresents an operation on a result, takes just the value, i.e. it doesn't care\nabout any previous error. To make it short:

      \n
      \n

      and_then allows us to run an operation, which can fail, on the correct result

      \n
      \n

      We parsed a y index and now we try to convert the x index with try_from\nagain, but on that result we use map rather than and_then, why would that be?

      \n
      pub fn map<U, F>(self, op: F) -> Result<U, E>
      where
      F: FnOnce(T) -> U
      \n

      Huh… map performs an operation that cannot fail. And finally we use\nunwrap_or which takes the value from result, or in case of an error returns the\ndefault that we define.

      \n

      How does this work then? If y is negative, the conversion fails and the error\npropagates all the way to unwrap_or, if y can be a correct usize value, then\nwe do the same with x. If x is negative, we propagate the error as with y,\nand if it's not, then we check whether it exceeds the higher bounds or not.

      \n

      Solution

      \n

      Relatively simple, you just need follow the rules and not get too smart, otherwise\nit will get back at you.

      \n

      Day 9: Rope Bridge

      \n
      tl;dr

      We get a rope with knots and we want to track how many different positions are\nvisited with the rope's tail.

      \n

      By this day, I have come to a conclusion that current skeleton for each day\ngenerates a lot of boilerplate. And even though it can be easily copied, it's\njust a waste of space and unnecessary code. Let's “simplify” this (on one end\nwhile creating monster on the other end). I've gone through what we need in the\npreparations for the AoC. Let's sum up our requirements:

      \n
        \n
      • parsing
      • \n
      • part 1 & 2
      • \n
      • running on sample / input
      • \n
      • tests
      • \n
      \n

      Parsing and implementation of both parts is code that changes each day and we\ncannot do anything about it. However running and testing can be simplified!

      \n

      Let's introduce and export a new module solution that will take care of all of\nthis. We will start by introducing a trait for each day.

      \n
      pub trait Solution<Input, Output: Display> {
      fn parse_input<P: AsRef<Path>>(pathname: P) -> Input;

      fn part_1(input: &Input) -> Output;
      fn part_2(input: &Input) -> Output;
      }
      \n

      This does a lot of work for us already, we have defined a trait and for each day\nwe will create a structure representing a specific day. That structure will also\nimplement the Solution trait.

      \n

      Now we need to get rid of the boilerplate, we can't get rid of the main function,\nbut we can at least move out the functionality.

      \n
      fn run(type_of_input: &str) -> Result<()>
      where
      Self: Sized,
      {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = Self::parse_input(format!(\"{}s/{}.txt\", type_of_input, Self::day()));

      info!(\"Part 1: {}\", Self::part_1(&input));
      info!(\"Part 2: {}\", Self::part_2(&input));

      Ok(())
      }

      fn main() -> Result<()>
      where
      Self: Sized,
      {
      Self::run(\"input\")
      }
      \n

      This is all part of the Solution trait, which can implement methods while being\ndependent on what is provided by the implementing types. In this case, we just\nneed to bound the Output type to implement Display that is necessary for the\ninfo! and format string there.

      \n

      Now we can get to first of the nasty things we are going to do… And it is the\nday() method that you can see being used when constructing path to the input\nfile. That method will generate a name of the file, e.g. day01 and we know that\nwe can somehow deduce it from the structure name, given we name it reasonably.

      \n
      fn day() -> String {
      let mut day = String::from(type_name::<Self>().split(\"::\").next().unwrap());
      day.make_ascii_lowercase();

      day.to_string()
      }
      \n
      type_name

      This feature is still experimental and considered to be internal, it is not\nadvised to use it any production code.

      \n

      And now we can get to the nastiest stuff 😩 We will generate the tests!

      \n

      We want to be able to generate tests for sample input in a following way:

      \n
      test_sample!(day_01, Day01, 42, 69);
      \n

      There's not much we can do, so we will write a macro to generate the tests for us.

      \n
      #[macro_export]
      macro_rules! test_sample {
      ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {
      #[cfg(test)]
      mod $mod_name {
      use super::*;

      #[test]
      fn test_part_1() {
      let sample =
      $day_struct::parse_input(&format!(\"samples/{}.txt\", $day_struct::day()));
      assert_eq!($day_struct::part_1(&sample), $part_1);
      }

      #[test]
      fn test_part_2() {
      let sample =
      $day_struct::parse_input(&format!(\"samples/{}.txt\", $day_struct::day()));
      assert_eq!($day_struct::part_2(&sample), $part_2);
      }
      }
      };
      }
      \n

      We have used it in a similar way as macros in C/C++, one of the things that we\ncan use to our advantage is defining “type” of the parameters for the macro. All\nparameters have their name prefixed with $ sign and you can define various “forms”\nof your macro. Let's go through it!

      \n

      We have following parameters:

      \n
        \n
      • $mod_name which represents the name for the module with tests, it is typed\nwith ident which means that we want a valid identifier to be passed in.
      • \n
      • $day_struct represents the structure that will be used for tests, it is typed\nwith tt which represents a token tree, in our case it is a type.
      • \n
      • $part_X represents the expected output for the Xth part and is of type expr\nwhich literally means an expression.
      • \n
      \n

      Apart from that we need to use #[macro_export] to mark the macro as exported\nfor usage outside of the module. Now our skeleton looks like:

      \n
      use aoc_2022::*;

      type Input = String;
      type Output = String;

      struct DayXX;
      impl Solution<Input, Output> for DayXX {
      fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
      file_to_string(pathname)
      }

      fn part_1(input: &Input) -> Output {
      todo!()
      }

      fn part_2(input: &Input) -> Output {
      todo!()
      }
      }

      fn main() -> Result<()> {
      // DayXX::run(\"sample\")
      DayXX::main()
      }

      // test_sample!(day_XX, DayXX, , );
      \n

      Solution

      \n

      Not much to talk about, it is relatively easy to simulate.

      \n

      Day 10: Cathode-Ray Tube

      \n
      tl;dr

      Emulating basic arithmetic operations on a CPU and drawing on CRT based on the\nCPU's accumulator.

      \n

      In this day I have discovered an issue with my design of the Solution trait.\nAnd the issue is caused by different types of Output for the part 1 and part 2.

      \n

      Problem is relatively simple and consists of simulating a CPU, I have approached\nit in a following way:

      \n
      fn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {
      instructions
      .iter()
      .fold(State::new(), |state, instruction| {
      state.execute(instruction, &mut out)
      });

      out
      }
      \n

      We just take the instructions, we have some state of the CPU and we execute the\ninstructions one-by-one. Perfect usage of the fold (or reduce as you may know\nit from other languages).

      \n

      You can also see that we have an Output type, so the question is how can we fix\nthat problem. And the answer is very simple and functional. Rust allows you to\nhave an enumeration that can bear some other values apart from the type itself.

      \n
      tip

      We could've seen something like this with the Result<T, E> type that can be\ndefined as

      enum Result<T, E> {
      Ok(T),
      Err(E)
      }
      What does that mean though?

      When we have an Ok value, it has the result itself, and when we get an Err\nvalue, it has the error. This also allows us to handle results in a rather\npretty way:

      match do_something(x) {
      Ok(y) => {
      println!(\"SUCCESS: {}\", y);
      },
      Err(y) => {
      eprintln!(\"ERROR: {}\", y);
      }
      }
      \n

      My solution has a following outline:

      \n
      fn execute(&self, i: &Instruction, output: &mut Output) -> State {
      // execute the instruction

      // collect results if necessary
      match output {
      Output::Part1(x) => self.execute_part_1(y, x),
      Output::Part2(x) => self.execute_part_2(y, x),
      }

      // return the obtained state
      new_state
      }
      \n

      You might think that it's a perfectly reasonable thing to do. Yes, but notice\nthat the match statement doesn't collect the changes in any way and also we\npass output by &mut, so it is shared across each iteration of the fold.

      \n

      The dirty and ingenious thing is that xs are passed by &mut too and therefore\nthey are directly modified by the helper functions. To sum it up and let it sit

      \n
      \n

      We are collecting the result into an enumeration that is shared\nacross all iterations of fold.

      \n
      \n

      Solution

      \n

      Similar to Day 9, but there are some technical details that can get you.

      \n

      Day 11: Monkey in the Middle

      \n
      tl;dr

      Simulation of monkeys throwing stuff around and measuring your stress levels\nwhile your stuff is being passed around.

      \n

      I think I decided to use regular expressions here for the first time, cause\nparsing the input was a pain.

      \n

      Also I didn't expect to implement Euclidean algorithm in Rust…

      \n

      Solution

      \n

      Again, we're just running a simulation. Though I must admit it was very easy to\nmake a small technical mistakes that could affect the final results very late.

      \n

      Day 12: Hill Climbing Algorithm

      \n
      tl;dr

      Finding shortest path up the hill and also shortest path down to the ground while\nalso rolling down the hill…

      \n

      As I have said in the tl;dr, we are looking for the shortest path, but the start\nand goal differ for the part 1 and 2. So I have decided to refactor my solution\nto a BFS algorithm that takes necessary parameters via functions:

      \n
      fn bfs<F, G>(
      graph: &[Vec<char>], start: &Position, has_edge: F, is_target: G
      ) -> Option<usize>
      where
      F: Fn(&[Vec<char>], &Position, &Position) -> bool,
      G: Fn(&[Vec<char>], &Position) -> bool
      \n

      We pass the initial vertex from the caller and everything else is left to the BFS\nalgorithm, based on the has_edge and is_target functions.

      \n

      This was easy! And that is not very usual in Rust once you want to pass around\nfunctions. 👀

      \n

      Solution

      \n

      Looking for the shortest path… Must be Dijkstra, right? Nope! Half of the\nReddit got jebaited though. In all fairness, nothing stops you from implementing\nthe Dijkstra's algorithm for finding the shortest path, but if you know that\nall connected vertices are in a unit (actually d=1d = 1d=1) distance from each other,\nthen you know that running Dijkstra is equivalent to running BFS, only with worse\ntime complexity, because of the priority heap instead of the queue.

      \n

      Day 13: Distress Signal

      \n
      tl;dr

      Processing packets with structured data from the distress signal.

      \n

      You can implement a lot of traits if you want to. It is imperative to implement\nordering on the packets. I had a typo, so I also proceeded to implement a Display\ntrait for debugging purposes:

      \n
      impl Display for Packet {
      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      match self {
      Packet::Integer(x) => write!(f, \"{x}\"),
      Packet::List(lst) => write!(f, \"[{}]\", lst.iter().map(|p| format!(\"{p}\")).join(\",\")),
      }
      }
      }
      \n

      Solution

      \n

      A lot of technical details… Parsing is nasty too…

      \n

      Day 14: Regolith Reservoir

      \n
      tl;dr

      Let's simulate falling sand grain-by-grain.

      \n

      Again, both parts are relatively similar with minimal changes, so it is a good\nidea to refactor it a bit. Similar approach to the BFS above. Also this is the\nfirst day where I ran into efficiency issues and had to redo my solution to speed\nit up just a bit.

      \n

      Solution

      \n

      Tedious.

      \n

      Post Mortem

      \n

      Indexing

      \n

      I was asked about the indexing after publishing the blog. And truly it is rather\ncomplicated topic, especially after releasing SliceIndex<I> trait. I couldn't\nleave it be, so I tried to implement the Index and IndexMut trait.

      \n
      note

      I have also mentioned that the SliceIndex trait is unsafe, but truth be told,\nonly unsafe part are the 2 methods that are named *unchecked*. Anyways, I will\nbe implementing the Index* traits for now, rather than the SliceIndex.

      \n

      It's relatively straightforward…

      \n
      impl<I, C> Index<Vector2D<I>> for [C]
      where
      I: Copy + TryInto<usize>,
      <I as TryInto<usize>>::Error: Debug,
      C: Index<usize>,
      {
      type Output = C::Output;

      fn index(&self, index: Vector2D<I>) -> &Self::Output {
      let (x, y): (usize, usize) =
      (index.x.try_into().unwrap(), index.y.try_into().unwrap());
      &self[y][x]
      }
      }

      impl<I, C> IndexMut<Vector2D<I>> for [C]
      where
      I: Copy + TryInto<usize>,
      <I as TryInto<usize>>::Error: Debug,
      C: IndexMut<usize>,
      {
      fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
      let (x, y): (usize, usize) =
      (index.x.try_into().unwrap(), index.y.try_into().unwrap());
      &mut self[y][x]
      }
      }
      \n

      We can see a lot of similarities to the implementation of index and index_mut\nfunctions. In the end, they are 1:1, just wrapped in the trait that provides a\nsyntax sugar for container[idx].

      \n
      note

      I have also switched from using the TryFrom to TryInto trait, since it better\nmatches what we are using, the .try_into rather than usize::try_from.

      Also implementing TryFrom automatically provides you with a TryInto trait,\nsince it is relatively easy to implement. Just compare the following:

      pub trait TryFrom<T>: Sized {
      type Error;

      fn try_from(value: T) -> Result<Self, Self::Error>;
      }

      pub trait TryInto<T>: Sized {
      type Error;

      fn try_into(self) -> Result<T, Self::Error>;
      }
      \n

      OK, so we have our trait implemented, we should be able to use container[index],\nright? Yes… but actually no 😦

      \n
      error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
      --> src/bin/day08.rs:26:18
      |
      26 | if trees[pos] > tallest {
      | ^^^ slice indices are of type `usize` or ranges of `usize`
      |
      = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
      = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

      error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
      --> src/bin/day08.rs:30:28
      |
      30 | max(tallest, trees[pos])
      | ^^^ slice indices are of type `usize` or ranges of `usize`
      |
      = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
      = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

      error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<isize>`
      --> src/bin/day08.rs:52:28
      |
      52 | let max_height = trees[position];
      | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
      |
      = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<isize>`
      = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<isize>>`
      \n

      Why? We have it implemented for the slices ([C]), why doesn't it work? Well,\nthe fun part consists of the fact that in other place, where we were using it,\nwe were passing the &[Vec<T>], but this is coming from a helper functions that\ntake &Vec<Vec<T>> instead. And… we don't implement Index and IndexMut for\nthose. Just for the slices. 🤯 What are we going to do about it?

      \n

      We can either start copy-pasting or be smarter about it… I choose to be smarter,\nso let's implement a macro! The only difference across the implementations are\nthe types of the outer containers. Implementation doesn't differ at all!

      \n

      Implementing the macro can be done in a following way:

      \n
      macro_rules! generate_indices {
      ($container:ty) => {
      impl<I, C> Index<Vector2D<I>> for $container
      where
      I: Copy + TryInto<usize>,
      <I as TryInto<usize>>::Error: Debug,
      C: Index<usize>,
      {
      type Output = C::Output;

      fn index(&self, index: Vector2D<I>) -> &Self::Output {
      let (x, y): (usize, usize) =
      (index.x.try_into().unwrap(), index.y.try_into().unwrap());
      &self[y][x]
      }
      }

      impl<I, C> IndexMut<Vector2D<I>> for $container
      where
      I: Copy + TryInto<usize>,
      <I as TryInto<usize>>::Error: Debug,
      C: IndexMut<usize>,
      {
      fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
      let (x, y): (usize, usize) =
      (index.x.try_into().unwrap(), index.y.try_into().unwrap());
      &mut self[y][x]
      }
      }
      };
      }
      \n

      And now we can simply do

      \n
      generate_indices!(VecDeque<C>);
      generate_indices!([C]);
      generate_indices!(Vec<C>);
      // generate_indices!([C; N], const N: usize);
      \n

      The last type (I took the inspiration from the implementations of the Index and\nIndexMut traits) is a bit problematic, because of the const N: usize part,\nwhich I haven't managed to be able to parse. And that's how I got rid of the error.

      \n
      note

      If I were to use 2D-indexing over [C; N] slices, I'd probably just go with the\ncopy-paste, cause the cost of this “monstrosity” outweighs the benefits of no DRY.

      \n

      Cause of the problem

      \n

      This issue is relatively funny. If you don't use any type aliases, just the raw\ntypes, you'll get suggested certain changes by the clippy. For example if you\nconsider the following piece of code

      \n
      fn get_sum(nums: &Vec<i32>) -> i32 {
      nums.iter().sum()
      }

      fn main() {
      let nums = vec![1, 2, 3];
      println!(\"Sum: {}\", get_sum(&nums));
      }
      \n

      and you run clippy on it, you will get

      \n
      Checking playground v0.0.1 (/playground)
      warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
      --> src/main.rs:1:18
      |
      1 | fn get_sum(nums: &Vec<i32>) -> i32 {
      | ^^^^^^^^^ help: change this to: `&[i32]`
      |
      = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
      = note: `#[warn(clippy::ptr_arg)]` on by default

      warning: `playground` (bin \"playground\") generated 1 warning
      Finished dev [unoptimized + debuginfo] target(s) in 0.61s
      \n

      However, if you introduce a type alias, such as

      \n
      type Numbers = Vec<i32>;
      \n

      Then clippy won't say anything, cause there is literally nothing to suggest.\nHowever the outcome is not the same…

      ", "url": "https://blog.mfocko.xyz/blog/aoc-2022/2nd-week", "title": "2nd week of Advent of Code '22 in Rust", "summary": "Surviving second week in Rust.", @@ -111,7 +111,7 @@ }, { "id": "https://blog.mfocko.xyz/blog/aoc-2022/1st-week", - "content_html": "

      Let's go through the first week of Advent of Code in Rust.

      \n
      note

      If you wish to have a look at the solutions, you can follow them on my GitLab.\nMore specifically in the /src/bin/.

      \n

      I will try to summarize my experience with using Rust for the AoC. Trying it out\nages ago, I believe it will be pain and suffering, but we will see. For each\nday I will also try to give a tl;dr of the problem, so that you can better imagine\nthe relation to my woes or 👍 moments.

      \n

      Day 1: Calorie Counting

      \n
      tl;dr

      As the name suggests, we get the calories of the food contained in the elves\nbackpacks and we want to choose the elf that has the most food ;)

      \n
      \n

      Wakey wakey!

      \n
      \n

      Programming in Rust at 6am definitely hits. I've also forgotten to mention how I\nhandle samples. With each puzzle you usually get a sample input and expected\noutput. You can use them to verify that your solution works, or usually doesn't.

      \n

      At first I've decided to put asserts into my main, something like

      \n
      assert_eq!(part_1(&sample), 24000);
      info!(\"Part 1: {}\", part_1(&input));

      assert_eq!(part_2(&sample), 45000);
      info!(\"Part 2: {}\", part_2(&input));
      \n

      However, once you get further, the sample input may take some time to run itself.\nSo in the end, I have decided to turn them into unit tests:

      \n
      #[cfg(test)]
      mod tests {
      use super::*;

      #[test]
      fn test_part_1() {
      let sample = parse_input(\"samples/day01.txt\");
      assert_eq!(part_1(&sample), 24000);
      }

      #[test]
      fn test_part_2() {
      let sample = parse_input(\"samples/day01.txt\");
      assert_eq!(part_2(&sample), 45000);
      }
      }
      \n

      And later on I have noticed, it's hard to tell the difference between the days,\nso I further renamed the mod from generic tests to reflect the days.

      \n

      Also after finishing the first day puzzle, I have installed an sccache to\ncache the builds, so that the build time is lower, cause it was kinda unbearable.

      \n

      Solution

      \n

      Well, it's a pretty simple problem. You just take the input, sum the calories and\nfind the biggest one. However, if we try to generalize to more than the biggest\none, the fun appears. We have few options:

      \n
        \n
      • keep all the calories, sort them, take what we need
      • \n
      • keep all the calories and use max heap
      • \n
      • use min heap and maintain at most N calories that we need
      • \n
      \n

      Day 2: Rock Paper Scissors

      \n
      tl;dr

      You want to know what score did you achieve while playing Rock Paper Scissors.\nAnd then you want to be strategic about it.

      \n

      Apart from the technical details of the puzzle, it went relatively smooth.

      \n

      Solution

      \n

      I took relatively naïve approach and then tried to simplify it.

      \n

      Day 3: Rucksack Reorganization

      \n
      tl;dr

      Let's go reorganize elves' backpacks! Each backpacks has 2 compartments and you\nwant to find the common item among those compartments. Each of them has priority,\nyou care only about the sum.

      \n

      This is the day where I started to fight the compiler and neither of us decided\nto give up. Let's dive into it \\o/

      \n
      Fun fact

      Fighting the compiler took me 30 minutes.

      \n

      We need to find a common item among 2 collections, that's an easy task, right?\nWe can construct 2 sets and find an intersection:

      \n
      let top: HashSet<i32> = [1, 2, 3].iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5].iter().collect();
      \n

      Now, the first issue that we encounter is caused by the fact that we are using\na slice (the […]), iterator of that returns references to the numbers.\nAnd we get immediately yelled at by the compiler, because the numbers are discarded\nafter running the .collect. To fix this, we can use .into_iter:

      \n
      let top: HashSet<i32> = [1, 2, 3].into_iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5].into_iter().collect();
      \n

      This way the numbers will get copied instead of referenced. OK, let's find the\nintersection of those 2 collections:

      \n
      println!(\"Common elements: {:?}\", top.intersection(&bottom));
      \n
      Common elements: [3]
      \n
      caution

      Notice that we need to do &bottom. It explicitly specifies that .intersection\nborrows the bottom, i.e. takes an immutable reference to it.

      \n

      That's what we want, right? Looks like it! \\o/

      \n

      Next part wants us to find the common element among all of the backpacks. OK, so\nthat should be fairly easy, we have an intersection and we want to find intersection\nover all of them.

      \n

      Let's have a look at the type of the .intersection

      \n
      pub fn intersection<'a>(
          &'a self,
          other: &'a HashSet<T, S>
      ) -> Intersection<'a, T, S>
      \n

      OK… Huh… But we have an example there!

      \n
      let intersection: HashSet<_> = a.intersection(&b).collect();
      \n

      Cool, that's all we need.

      \n
      let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
      let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
      let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

      let intersection: HashSet<_> = top.intersection(&bottom).collect();
      println!(\"Intersection: {:?}\", intersection);
      \n
      Intersection: {3, 4}
      \n

      Cool, so let's do the intersection with the top_2:

      \n
      let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
      let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
      let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

      let intersection: HashSet<_> = top.intersection(&bottom).collect();
      let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
      println!(\"Intersection: {:?}\", intersection);
      \n

      And we get yelled at by the compiler:

      \n
      error[E0308]: mismatched types
      --> src/main.rs:10:58
      |
      10 | let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
      | ------------ ^^^^^^ expected `&i32`, found `i32`
      | |
      | arguments to this function are incorrect
      |
      = note: expected reference `&HashSet<&i32>`
      found reference `&HashSet<i32>`
      \n

      /o\\ What the hell is going on here? Well, the funny thing is, that this operation\ndoesn't return the elements themselves, but the references to them and when we pass\nthe third set, it has just the values themselves, without any references.

      \n
      tip

      It may seem as a very weird decision, but in fact it makes some sense… It allows\nyou to do intersection of items that may not be possible to copy. Overall this is\na “tax” for having a borrow checker drilling your ass having your back and\nmaking sure you're not doing something naughty that may cause an undefined\nbehavior.

      \n

      To resolve this we need to get an iterator that clones the elements:

      \n
      let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
      let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
      let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

      let intersection: HashSet<_> = top.intersection(&bottom).cloned().collect();
      let intersection: HashSet<_> = intersection.intersection(&top_2).cloned().collect();
      let intersection: HashSet<_> = intersection.intersection(&bottom_2).cloned().collect();
      println!(\"Intersection: {:?}\", intersection);
      \n
      Intersection: {4}
      \n

      Solution

      \n

      The approach is pretty simple, if you omit the 1on1 with the compiler. You just\nhave some fun with the set operations :)

      \n

      Day 4: Camp Cleanup

      \n
      tl;dr

      Elves are cleaning up the camp and they got overlapping sections to clean up.\nFind how many overlap and can take the day off.

      \n

      RangeInclusive is your friend not an enemy :)

      \n

      Solution

      \n

      Relatively easy, you just need to parse the input and know what you want. Rust's\nRangeInclusive type helped a lot, cause it took care of all abstractions.

      \n

      Day 5: Supply Stacks

      \n
      tl;dr

      Let's play with stacks of crates.

      \n

      Very easy problem with very annoying input. You can judge yourself:

      \n
          [D]
      [N] [C]
      [Z] [M] [P]
      1 2 3

      move 1 from 2 to 1
      move 3 from 1 to 3
      move 2 from 2 to 1
      move 1 from 1 to 2
      \n

      Good luck transforming that into something reasonable :)

      \n
      Fun fact

      Took me 40 minutes to parse this reasonably, including fighting the compiler.

      \n

      Solution

      \n

      For the initial solution I went with a manual solution (as in I have done all\nthe work. Later on I have decided to explore the std and interface of the\nstd::vec::Vec and found split_off which takes an index and splits (duh)\nthe vector:

      \n
      let mut vec = vec![1, 2, 3];
      let vec2 = vec.split_off(1);
      assert_eq!(vec, [1]);
      assert_eq!(vec2, [2, 3]);
      \n

      This helped me simplify my solution a lot and also get rid of some edge cases.

      \n

      Day 6: Tuning Trouble

      \n
      tl;dr

      Finding start of the message in a very weird protocol. Start of the message is\ndenoted by NNN unique consecutive characters.

      \n

      Solution

      \n

      A lot of different approaches, knowing that we are dealing with input consisting\nsolely of ASCII letters, I bit the bullet and went with sliding window and\nconstructing sets from that window, checking if the set is as big as the window.

      \n

      One possible optimization could consist of keeping a bit-vector (i.e. usize\nvariable) of encountered characters and updating it as we go. However this has\na different issue and that is removal of the characters from the left side of the\nwindow. We don't know if the same character is not included later on.

      \n

      Other option is to do similar thing, but keeping the frequencies of the letters,\nand again knowing we have only ASCII letters we can optimize by having a vector\nof 26 elements that keeps count for each lowercase letter.

      \n

      Day 7: No Space Left On Device

      \n
      tl;dr

      Let's simulate du to get some stats about our file system and then pinpoint\ndirectories that take a lot of space and should be deleted.

      \n
      \n

      I was waiting for this moment, and yet it got me!\nimagine me swearing for hours

      \n
      \n

      Solution

      \n

      We need to “build” a file system from the input that is given in a following form:

      \n
      $ cd /
      $ ls
      dir a
      14848514 b.txt
      8504156 c.dat
      dir d
      $ cd a
      $ ls
      dir e
      29116 f
      2557 g
      62596 h.lst
      $ cd e
      $ ls
      584 i
      $ cd ..
      $ cd ..
      $ cd d
      $ ls
      4060174 j
      8033020 d.log
      5626152 d.ext
      7214296 k
      \n

      There are few ways in which you can achieve this and also you can assume some\npreconditions, but why would we do that, right? :)

      \n

      You can “slap” this in either HashMap or BTreeMap and call it a day.\nAnd that would be boring…

      \n
      tip

      BTreeMap is quite fitting for this, don't you think?

      \n

      I always wanted to try allocation on heap in Rust, so I chose to implement a tree.\nI fought with the Box<T> for some time and was losing…

      \n

      Then I looked up some implementations of trees or linked lists and decided to try\nRc<Cell<T>>. And I got my ass whopped by the compiler once again. /o\\

      \n
      tip

      Box<T> represents a dynamically allocated memory on heap. It is a single pointer,\nyou can imagine this as std::unique_ptr<T> in C++.

      Rc<T> represents a dynamically allocated memory on heap. On top of that it is\nreference counted (that's what the Rc stands for). You can imagine this as\nstd::shared_ptr<T> in C++.

      Now the fun stuff. Neither of them lets you mutate the contents of the memory.

      Cell<T> allows you to mutate the memory. Can be used reasonably with types that\ncan be copied, because the memory safety is guaranteed by copying the contents\nwhen there is more than one mutable reference to the memory.

      RefCell<T> is similar to the Cell<T>, but the borrowing rules (how many mutable\nreferences are present) are checked dynamically.

      So in the end, if you want something like std::shared_ptr<T> in Rust, you want\nto have Rc<RefCell<T>>.

      \n

      So, how are we going to represent the file system then? We will use an enumeration,\nhehe, which is an algebraic data type that can store some stuff in itself 😩

      \n
      type FileHandle = Rc<RefCell<AocFile>>;

      #[derive(Debug)]
      enum AocFile {
      File(usize),
      Directory(BTreeMap<String, FileHandle>),
      }
      \n

      Let's go over it! FileHandle represents dynamically allocated AocFile, not\nmuch to discuss. What does the #[derive(Debug)] do though? It lets us to print\nout the value of that enumeration, it's derived, so it's not as good as if we had\nimplemented it ourselves, but it's good enough for debugging, hence the name.

      \n

      Now to the fun part! AocFile value can be represented in two ways:

      \n
        \n
      • File(usize), e.g. AocFile::File(123) and we can pattern match it, if we\nneed to
      • \n
      • Directory(BTreeMap<String, FileHandle>) will represent the directory and will\ncontain map matching the name of the files (or directories) within to their\nrespective file handles
      • \n
      \n

      I will omit the details about constructing this file system, cause there are a lot\nof technicalities introduced by the nature of the input. However if you are\ninterested, you can have a look at my solution.

      \n

      We need to find small enough directories and also find the smallest directory that\nwill free enough space. Now the question is, how could we do that. And there are\nmultiple ways I will describe.

      \n

      I have chosen to implement tree catamorphism 😩. It is basically a fold\nover a tree data structure. We descent down into the leaves and propagate computed\nresults all the way to the root. You can also notice that this approach is very\nsimilar to dynamic programming, we find overlapping sections of the computation\nand try to minimize the additional work (in this case: we need to know sizes of\nour descendants, but we have already been there).

      \n

      Another approach that has been suggested to me few days later is running DFS on\nthe graph. And, funnily enough, we would still need to combine what we found in\nthe branches where we descent. So in the end, it would work very similarly to my\nsolution.

      \n

      One of the more exotic options would be precomputing the required information at\nthe same time as parsing. That could be done by adding additional fields to the\nnodes which would allow storing such information and updating it as we construct\nthe file system.

      \n

      Post Mortem

      \n

      Things that have been brought up in the discussion later on.

      \n

      Rc<T> vs Rc<RefCell<T>>

      \n

      It has been brought up that I have a contradicting statement regarding the\ndynamically allocated memory. Specifically:

      \n
        \n
      • You can imagine Rc<T> as an std::shared_ptr<T> (in C++)
      • \n
      • When you want an equivalent of std::shared_ptr<T>, you want to use\nRc<RefCell<T>>
      • \n
      \n

      Now, in Rust it is a bit more complicated, because the type that represents the\n“shared pointer” is Rc<T>. What RefCell<T> does is making sure that there is\nonly one “owner” of a mutable reference at a time (and dynamically, as opposed\nto the Cell<T>).

      \n

      Therefore to be precise and correct about the equivalents of std::shared_ptr<T>\nin Rust, we can say that

      \n
        \n
      • Rc<T> is an equivalent of a const std::shared_ptr<T>,
      • \n
      • and Rc<RefCell<T>> is an equivalent of a std::shared_ptr<T>.
      • \n
      \n

      You can easily see that they only differ in the mutability. (And even that is not\nas simple as it seems, because there is also Cell<T>)

      ", + "content_html": "

      Let's go through the first week of Advent of Code in Rust.

      \n
      note

      If you wish to have a look at the solutions, you can follow them on my GitLab.\nMore specifically in the /src/bin/.

      \n

      I will try to summarize my experience with using Rust for the AoC. Trying it out\nages ago, I believe it will be pain and suffering, but we will see. For each\nday I will also try to give a tl;dr of the problem, so that you can better imagine\nthe relation to my woes or 👍 moments.

      \n

      Day 1: Calorie Counting

      \n
      tl;dr

      As the name suggests, we get the calories of the food contained in the elves\nbackpacks and we want to choose the elf that has the most food ;)

      \n
      \n

      Wakey wakey!

      \n
      \n

      Programming in Rust at 6am definitely hits. I've also forgotten to mention how I\nhandle samples. With each puzzle you usually get a sample input and expected\noutput. You can use them to verify that your solution works, or usually doesn't.

      \n

      At first I've decided to put asserts into my main, something like

      \n
      assert_eq!(part_1(&sample), 24000);
      info!(\"Part 1: {}\", part_1(&input));

      assert_eq!(part_2(&sample), 45000);
      info!(\"Part 2: {}\", part_2(&input));
      \n

      However, once you get further, the sample input may take some time to run itself.\nSo in the end, I have decided to turn them into unit tests:

      \n
      #[cfg(test)]
      mod tests {
      use super::*;

      #[test]
      fn test_part_1() {
      let sample = parse_input(\"samples/day01.txt\");
      assert_eq!(part_1(&sample), 24000);
      }

      #[test]
      fn test_part_2() {
      let sample = parse_input(\"samples/day01.txt\");
      assert_eq!(part_2(&sample), 45000);
      }
      }
      \n

      And later on I have noticed, it's hard to tell the difference between the days,\nso I further renamed the mod from generic tests to reflect the days.

      \n

      Also after finishing the first day puzzle, I have installed an sccache to\ncache the builds, so that the build time is lower, cause it was kinda unbearable.

      \n

      Solution

      \n

      Well, it's a pretty simple problem. You just take the input, sum the calories and\nfind the biggest one. However, if we try to generalize to more than the biggest\none, the fun appears. We have few options:

      \n
        \n
      • keep all the calories, sort them, take what we need
      • \n
      • keep all the calories and use max heap
      • \n
      • use min heap and maintain at most N calories that we need
      • \n
      \n

      Day 2: Rock Paper Scissors

      \n
      tl;dr

      You want to know what score did you achieve while playing Rock Paper Scissors.\nAnd then you want to be strategic about it.

      \n

      Apart from the technical details of the puzzle, it went relatively smooth.

      \n

      Solution

      \n

      I took relatively naïve approach and then tried to simplify it.

      \n

      Day 3: Rucksack Reorganization

      \n
      tl;dr

      Let's go reorganize elves' backpacks! Each backpacks has 2 compartments and you\nwant to find the common item among those compartments. Each of them has priority,\nyou care only about the sum.

      \n

      This is the day where I started to fight the compiler and neither of us decided\nto give up. Let's dive into it \\o/

      \n
      Fun fact

      Fighting the compiler took me 30 minutes.

      \n

      We need to find a common item among 2 collections, that's an easy task, right?\nWe can construct 2 sets and find an intersection:

      \n
      let top: HashSet<i32> = [1, 2, 3].iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5].iter().collect();
      \n

      Now, the first issue that we encounter is caused by the fact that we are using\na slice (the […]), iterator of that returns references to the numbers.\nAnd we get immediately yelled at by the compiler, because the numbers are discarded\nafter running the .collect. To fix this, we can use .into_iter:

      \n
      let top: HashSet<i32> = [1, 2, 3].into_iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5].into_iter().collect();
      \n

      This way the numbers will get copied instead of referenced. OK, let's find the\nintersection of those 2 collections:

      \n
      println!(\"Common elements: {:?}\", top.intersection(&bottom));
      \n
      Common elements: [3]
      \n
      caution

      Notice that we need to do &bottom. It explicitly specifies that .intersection\nborrows the bottom, i.e. takes an immutable reference to it.

      \n

      That's what we want, right? Looks like it! \\o/

      \n

      Next part wants us to find the common element among all of the backpacks. OK, so\nthat should be fairly easy, we have an intersection and we want to find intersection\nover all of them.

      \n

      Let's have a look at the type of the .intersection

      \n
      pub fn intersection<'a>(
          &'a self,
          other: &'a HashSet<T, S>
      ) -> Intersection<'a, T, S>
      \n

      OK… Huh… But we have an example there!

      \n
      let intersection: HashSet<_> = a.intersection(&b).collect();
      \n

      Cool, that's all we need.

      \n
      let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
      let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
      let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

      let intersection: HashSet<_> = top.intersection(&bottom).collect();
      println!(\"Intersection: {:?}\", intersection);
      \n
      Intersection: {3, 4}
      \n

      Cool, so let's do the intersection with the top_2:

      \n
      let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
      let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
      let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

      let intersection: HashSet<_> = top.intersection(&bottom).collect();
      let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
      println!(\"Intersection: {:?}\", intersection);
      \n

      And we get yelled at by the compiler:

      \n
      error[E0308]: mismatched types
      --> src/main.rs:10:58
      |
      10 | let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
      | ------------ ^^^^^^ expected `&i32`, found `i32`
      | |
      | arguments to this function are incorrect
      |
      = note: expected reference `&HashSet<&i32>`
      found reference `&HashSet<i32>`
      \n

      /o\\ What the hell is going on here? Well, the funny thing is, that this operation\ndoesn't return the elements themselves, but the references to them and when we pass\nthe third set, it has just the values themselves, without any references.

      \n
      tip

      It may seem as a very weird decision, but in fact it makes some sense… It allows\nyou to do intersection of items that may not be possible to copy. Overall this is\na “tax” for having a borrow checker drilling your ass having your back and\nmaking sure you're not doing something naughty that may cause an undefined\nbehavior.

      \n

      To resolve this we need to get an iterator that clones the elements:

      \n
      let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
      let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
      let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
      let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

      let intersection: HashSet<_> = top.intersection(&bottom).cloned().collect();
      let intersection: HashSet<_> = intersection.intersection(&top_2).cloned().collect();
      let intersection: HashSet<_> = intersection.intersection(&bottom_2).cloned().collect();
      println!(\"Intersection: {:?}\", intersection);
      \n
      Intersection: {4}
      \n

      Solution

      \n

      The approach is pretty simple, if you omit the 1on1 with the compiler. You just\nhave some fun with the set operations :)

      \n

      Day 4: Camp Cleanup

      \n
      tl;dr

      Elves are cleaning up the camp and they got overlapping sections to clean up.\nFind how many overlap and can take the day off.

      \n

      RangeInclusive is your friend not an enemy :)

      \n

      Solution

      \n

      Relatively easy, you just need to parse the input and know what you want. Rust's\nRangeInclusive type helped a lot, cause it took care of all abstractions.

      \n

      Day 5: Supply Stacks

      \n
      tl;dr

      Let's play with stacks of crates.

      \n

      Very easy problem with very annoying input. You can judge yourself:

      \n
          [D]
      [N] [C]
      [Z] [M] [P]
      1 2 3

      move 1 from 2 to 1
      move 3 from 1 to 3
      move 2 from 2 to 1
      move 1 from 1 to 2
      \n

      Good luck transforming that into something reasonable :)

      \n
      Fun fact

      Took me 40 minutes to parse this reasonably, including fighting the compiler.

      \n

      Solution

      \n

      For the initial solution I went with a manual solution (as in I have done all\nthe work. Later on I have decided to explore the std and interface of the\nstd::vec::Vec and found split_off which takes an index and splits (duh)\nthe vector:

      \n
      let mut vec = vec![1, 2, 3];
      let vec2 = vec.split_off(1);
      assert_eq!(vec, [1]);
      assert_eq!(vec2, [2, 3]);
      \n

      This helped me simplify my solution a lot and also get rid of some edge cases.

      \n

      Day 6: Tuning Trouble

      \n
      tl;dr

      Finding start of the message in a very weird protocol. Start of the message is\ndenoted by NNN unique consecutive characters.

      \n

      Solution

      \n

      A lot of different approaches, knowing that we are dealing with input consisting\nsolely of ASCII letters, I bit the bullet and went with sliding window and\nconstructing sets from that window, checking if the set is as big as the window.

      \n

      One possible optimization could consist of keeping a bit-vector (i.e. usize\nvariable) of encountered characters and updating it as we go. However this has\na different issue and that is removal of the characters from the left side of the\nwindow. We don't know if the same character is not included later on.

      \n

      Other option is to do similar thing, but keeping the frequencies of the letters,\nand again knowing we have only ASCII letters we can optimize by having a vector\nof 26 elements that keeps count for each lowercase letter.

      \n

      Day 7: No Space Left On Device

      \n
      tl;dr

      Let's simulate du to get some stats about our file system and then pinpoint\ndirectories that take a lot of space and should be deleted.

      \n
      \n

      I was waiting for this moment, and yet it got me!\nimagine me swearing for hours

      \n
      \n

      Solution

      \n

      We need to “build” a file system from the input that is given in a following form:

      \n
      $ cd /
      $ ls
      dir a
      14848514 b.txt
      8504156 c.dat
      dir d
      $ cd a
      $ ls
      dir e
      29116 f
      2557 g
      62596 h.lst
      $ cd e
      $ ls
      584 i
      $ cd ..
      $ cd ..
      $ cd d
      $ ls
      4060174 j
      8033020 d.log
      5626152 d.ext
      7214296 k
      \n

      There are few ways in which you can achieve this and also you can assume some\npreconditions, but why would we do that, right? :)

      \n

      You can “slap” this in either HashMap or BTreeMap and call it a day.\nAnd that would be boring…

      \n
      tip

      BTreeMap is quite fitting for this, don't you think?

      \n

      I always wanted to try allocation on heap in Rust, so I chose to implement a tree.\nI fought with the Box<T> for some time and was losing…

      \n

      Then I looked up some implementations of trees or linked lists and decided to try\nRc<Cell<T>>. And I got my ass whopped by the compiler once again. /o\\

      \n
      tip

      Box<T> represents a dynamically allocated memory on heap. It is a single pointer,\nyou can imagine this as std::unique_ptr<T> in C++.

      Rc<T> represents a dynamically allocated memory on heap. On top of that it is\nreference counted (that's what the Rc stands for). You can imagine this as\nstd::shared_ptr<T> in C++.

      Now the fun stuff. Neither of them lets you mutate the contents of the memory.

      Cell<T> allows you to mutate the memory. Can be used reasonably with types that\ncan be copied, because the memory safety is guaranteed by copying the contents\nwhen there is more than one mutable reference to the memory.

      RefCell<T> is similar to the Cell<T>, but the borrowing rules (how many mutable\nreferences are present) are checked dynamically.

      So in the end, if you want something like std::shared_ptr<T> in Rust, you want\nto have Rc<RefCell<T>>.

      \n

      So, how are we going to represent the file system then? We will use an enumeration,\nhehe, which is an algebraic data type that can store some stuff in itself 😩

      \n
      type FileHandle = Rc<RefCell<AocFile>>;

      #[derive(Debug)]
      enum AocFile {
      File(usize),
      Directory(BTreeMap<String, FileHandle>),
      }
      \n

      Let's go over it! FileHandle represents dynamically allocated AocFile, not\nmuch to discuss. What does the #[derive(Debug)] do though? It lets us to print\nout the value of that enumeration, it's derived, so it's not as good as if we had\nimplemented it ourselves, but it's good enough for debugging, hence the name.

      \n

      Now to the fun part! AocFile value can be represented in two ways:

      \n
        \n
      • File(usize), e.g. AocFile::File(123) and we can pattern match it, if we\nneed to
      • \n
      • Directory(BTreeMap<String, FileHandle>) will represent the directory and will\ncontain map matching the name of the files (or directories) within to their\nrespective file handles
      • \n
      \n

      I will omit the details about constructing this file system, cause there are a lot\nof technicalities introduced by the nature of the input. However if you are\ninterested, you can have a look at my solution.

      \n

      We need to find small enough directories and also find the smallest directory that\nwill free enough space. Now the question is, how could we do that. And there are\nmultiple ways I will describe.

      \n

      I have chosen to implement tree catamorphism 😩. It is basically a fold\nover a tree data structure. We descent down into the leaves and propagate computed\nresults all the way to the root. You can also notice that this approach is very\nsimilar to dynamic programming, we find overlapping sections of the computation\nand try to minimize the additional work (in this case: we need to know sizes of\nour descendants, but we have already been there).

      \n

      Another approach that has been suggested to me few days later is running DFS on\nthe graph. And, funnily enough, we would still need to combine what we found in\nthe branches where we descent. So in the end, it would work very similarly to my\nsolution.

      \n

      One of the more exotic options would be precomputing the required information at\nthe same time as parsing. That could be done by adding additional fields to the\nnodes which would allow storing such information and updating it as we construct\nthe file system.

      \n

      Post Mortem

      \n

      Things that have been brought up in the discussion later on.

      \n

      Rc<T> vs Rc<RefCell<T>>

      \n

      It has been brought up that I have a contradicting statement regarding the\ndynamically allocated memory. Specifically:

      \n
        \n
      • You can imagine Rc<T> as an std::shared_ptr<T> (in C++)
      • \n
      • When you want an equivalent of std::shared_ptr<T>, you want to use\nRc<RefCell<T>>
      • \n
      \n

      Now, in Rust it is a bit more complicated, because the type that represents the\n“shared pointer” is Rc<T>. What RefCell<T> does is making sure that there is\nonly one “owner” of a mutable reference at a time (and dynamically, as opposed\nto the Cell<T>).

      \n

      Therefore to be precise and correct about the equivalents of std::shared_ptr<T>\nin Rust, we can say that

      \n
        \n
      • Rc<T> is an equivalent of a const std::shared_ptr<T>,
      • \n
      • and Rc<RefCell<T>> is an equivalent of a std::shared_ptr<T>.
      • \n
      \n

      You can easily see that they only differ in the mutability. (And even that is not\nas simple as it seems, because there is also Cell<T>)

      ", "url": "https://blog.mfocko.xyz/blog/aoc-2022/1st-week", "title": "1st week of Advent of Code '22 in Rust", "summary": "Surviving first week in Rust.", @@ -128,7 +128,7 @@ }, { "id": "https://blog.mfocko.xyz/blog/aoc-2022/intro", - "content_html": "

      Let's talk about the preparations for this year's Advent of Code.

      \n

      Choosing a language

      \n

      When choosing a language for AoC, you usually want a language that gives you a\nquick feedback which allows you to iterate quickly to the solution of the puzzle.\nOne of the most common choices is Python, many people also use JavaScript or Ruby.

      \n

      Given the competitive nature of the AoC and popularity among competitive programming,\nC++ might be also a very good choice. Only if you are familiar with it, I guess…

      \n

      If you want a challenge, you might also choose to rotate the languages each day.\nThough I prefer to use only one language.

      \n

      For this year I have been deciding between Rust, C++ and Pascal or Ada.

      \n

      I have tried Rust last year and have survived with it for 3 days and then gave\nup and switched to Kotlin, which was pretty good given it is “Java undercover”.\nI pretty much like the ideas behind Rust, I am not sure about the whole cult and\nimplementation of those ideas though. After some years with C/C++, I would say\nthat Rust feels too safe for my taste and tries to “punish me” even for the\nmost trivial things.

      \n

      C++ is a very robust, but also comes with a wide variety of options providing you\nthe ability to shoot yourself in the leg. I have tried to solve few days of previous\nAdvent of Code events, it was relatively easy to solve the problems in C++, given\nthat I do not admit writing my own iterator for enumerate

      \n

      Pascal or Ada were meme choices :) Ada is heavily inspired by Pascal and has a\npretty nice standard library that offers enough to be able to quickly solve some\nproblems in it. However the toolkit is questionable :/

      \n

      Choosing libraries

      \n

      Preparations for Rust

      \n

      All of the sources, later on including solutions, can be found at my\nGitLab.

      \n

      Toolkit

      \n

      Since we are using Rust, we are going to use a Cargo and more than likely VSCode\nwith rust-analyzer. Because of my choice of libraries, we will also introduce\na .envrc file that can be used by direnv, which allows you to set specific\nenvironment variables when you enter a directory. In our case, we will use

      \n
      # to show nice backtrace when using the color-eyre
      export RUST_BACKTRACE=1

      # to catch logs generated by tracing
      export RUST_LOG=trace
      \n

      And for the one of the most obnoxious things ever, we will use a script to download\nthe inputs instead of “clicking, opening and copying to a file1. There is\nno need to be fancy, so we will adjust Python script by Martin2.

      \n
      #!/usr/bin/env python3

      import datetime
      import yaml
      import requests
      import sys


      def load_config():
      with open(\"env.yaml\", \"r\") as f:
      js = yaml.load(f, Loader=yaml.Loader)
      return js[\"session\"], js[\"year\"]


      def get_input(session, year, day):
      return requests.get(
      f\"https://adventofcode.com/{year}/day/{day}/input\",
      cookies={\"session\": session},
      headers={
      \"User-Agent\": \"{repo} by {mail}\".format(
      repo=\"gitlab.com/mfocko/advent-of-code-2022\",
      mail=\"me@mfocko.xyz\",
      )
      },
      ).content.decode(\"utf-8\")


      def main():
      day = datetime.datetime.now().day
      if len(sys.argv) == 2:
      day = sys.argv[1]

      session, year = load_config()
      problem_input = get_input(session, year, day)

      with open(f\"./inputs/day{day:>02}.txt\", \"w\") as f:
      f.write(problem_input)


      if __name__ == \"__main__\":
      main()
      \n

      If the script is called without any arguments, it will deduce the day from the\nsystem, so we do not need to change the day every morning. It also requires a\nconfiguration file:

      \n
      # env.yaml
      session: ‹your session cookie›
      year: 2022
      \n

      Libraries

      \n

      Looking at the list of the libraries, I have chosen “a lot” of them. Let's walk\nthrough each of them.

      \n

      tracing and tracing-subscriber are the crates that can be used for tracing\nand logging of your Rust programs, there are also other crates that can help you\nwith providing backtrace to the Sentry in case you have deployed your application\nsomewhere and you want to watch over it. In our use case we will just utilize the\nmacros for debugging in the terminal.

      \n

      thiserror, anyhow and color-eyre are used for error reporting.\nthiserror is a very good choice for libraries, cause it extends the Error\nfrom the std and allows you to create more convenient error types. Next is\nanyhow which kinda builds on top of the thiserror and provides you with simpler\nerror handling in binaries3. And finally we have color-eyre which, as I found\nout later, is a colorful (wink wink) extension of eyre which is fork of anyhow\nwhile supporting customized reports.

      \n

      In the end I have decided to remove thiserror and anyhow, since first one is\nsuitable for libraries and the latter was basically fully replaced by {color-,}eyre.

      \n

      regex and lazy_static are a very good and also, I hope, self-explanatory\ncombination. lazy_static allows you to have static variables that must be initialized\nduring runtime.

      \n

      itertools provides some nice extensions to the iterators from the std.

      \n

      My own “library”

      \n

      When creating the crate for this year's Advent of Code, I have chosen a library\ntype. Even though standard library is huge, some things might not be included and\nalso we can follow KISS. I have 2 modules that my “library” exports, one for\nparsing and one for 2D vector (that gets used quite often during Advent of Code).

      \n

      Key part is, of course, processing the input and my library exports following\nfunctions that get used a lot:

      \n
      /// Reads file to the string.
      pub fn file_to_string<P: AsRef<Path>>(pathname: P) -> String;

      /// Reads file and returns it as a vector of characters.
      pub fn file_to_chars<P: AsRef<Path>>(pathname: P) -> Vec<char>;

      /// Reads file and returns a vector of parsed structures. Expects each structure
      /// on its own line in the file. And `T` needs to implement `FromStr` trait.
      pub fn file_to_structs<P: AsRef<Path>, T: FromStr>(pathname: P) -> Vec<T>
      where
      <T as FromStr>::Err: Debug;

      /// Converts iterator over strings to a vector of parsed structures. `T` needs
      /// to implement `FromStr` trait and its error must derive `Debug` trait.
      pub fn strings_to_structs<T: FromStr, U>(
      iter: impl Iterator<Item = U>
      ) -> Vec<T>
      where
      <T as std::str::FromStr>::Err: std::fmt::Debug,
      U: Deref<Target = str>;

      /// Reads file and returns it as a vector of its lines.
      pub fn file_to_lines<P: AsRef<Path>>(pathname: P) -> Vec<String>;
      \n

      As for the vector, I went with a rather simple implementation that allows only\naddition of the vectors for now and accessing the elements via functions x()\nand y(). Also the vector is generic, so we can use it with any numeric type we\nneed.

      \n

      Skeleton

      \n

      We can also prepare a template to quickly bootstrap each of the days. We know\nthat each puzzle has 2 parts, which means that we can start with 2 functions that\nwill solve them.

      \n
      fn part1(input: &Input) -> Output {
      todo!()
      }

      fn part2(input: &Input) -> Output {
      todo!()
      }
      \n

      Both functions take reference to the input and return some output (in majority\nof puzzles, it is the same type). todo!() can be used as a nice placeholder,\nit also causes a panic when reached and we could also provide some string with\nan explanation, e.g. todo!(\"part 1\"). We have not given functions a specific\ntype and to avoid as much copy-paste as possible, we will introduce type aliases.

      \n
      type Input = String;
      type Output = i32;
      \n
      tip

      This allows us to quickly adjust the types only in one place without the need to\ndo regex-replace or replace them manually.

      \n

      For each day we get a personalized input that is provided as a text file. Almost\nall the time, we would like to get some structured type out of that input, and\ntherefore it makes sense to introduce a new function that will provide the parsing\nof the input.

      \n
      fn parse_input(path: &str) -> Input {
      todo!()
      }
      \n

      This “parser” will take a path to the file, just in case we would like to run the\nsample instead of input.

      \n

      OK, so now we can write a main function that will take all of the pieces and\nrun them.

      \n
      fn main() {
      let input = parse_input(\"inputs/dayXX.txt\");

      println!(\"Part 1: {}\", part_1(&input));
      println!(\"Part 2: {}\", part_2(&input));
      }
      \n

      This would definitely do :) But we have installed a few libraries and we want to\nuse them. In this part we are going to utilize tracing (for tracing, duh…)\nand color-eyre (for better error reporting, e.g. from parsing).

      \n
      fn main() -> Result<()> {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = parse_input(\"inputs/dayXX.txt\");

      info!(\"Part 1: {}\", part_1(&input));
      info!(\"Part 2: {}\", part_2(&input));

      Ok(())
      }
      \n

      The first statement will set up tracing and configure it to print out the logs to\nterminal, based on the environment variable. We also change the formatting a bit,\nsince we do not need all the fancy features of the logger. Pure initialization\nwould get us logs like this:

      \n
      2022-12-11T19:53:19.975343Z  INFO day01: Part 1: 0
      \n

      However after running that command, we will get the following:

      \n
       INFO src/bin/day01.rs:35: Part 1: 0
      \n

      And the color_eyre::install()? is quite straightforward. We just initialize the\nerror reporting by color eyre.

      \n
      caution

      Notice that we had to add Ok(()) to the end of the function and adjust the\nreturn type of the main to Result<()>. It is caused by the color eyre that\ncan be installed only once and therefore it can fail, that is how we got the ?\nat the end of the ::install which unwraps the »result« of the installation.

      \n

      Overall we will get to a template like this:

      \n
      use aoc_2022::*;

      use color_eyre::eyre::Result;
      use tracing::info;
      use tracing_subscriber::EnvFilter;

      type Input = String;
      type Output = i32;

      fn parse_input(path: &str) -> Input {
      todo!()
      }

      fn part1(input: &Input) -> Output {
      todo!()
      }

      fn part2(input: &Input) -> Output {
      todo!()
      }

      fn main() -> Result<()> {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = parse_input(\"inputs/dayXX.txt\");

      info!(\"Part 1: {}\", part_1(&input));
      info!(\"Part 2: {}\", part_2(&input));

      Ok(())
      }
      \n

      Footnotes

      \n
        \n
      1. \n

        Copy-pasting might be a relaxing thing to do, but you can also discover\nnasty stuff about your PC. See this Reddit post and the comment.

        \n
      2. \n
      3. \n

        GitHub profile

        \n
      4. \n
      5. \n

        Even though you can use it even for libraries, but handling errors from\nlibraries using anyhow is nasty… You will be the stinky one ;)

        \n
      6. \n
      \n
      ", + "content_html": "

      Let's talk about the preparations for this year's Advent of Code.

      \n

      Choosing a language

      \n

      When choosing a language for AoC, you usually want a language that gives you a\nquick feedback which allows you to iterate quickly to the solution of the puzzle.\nOne of the most common choices is Python, many people also use JavaScript or Ruby.

      \n

      Given the competitive nature of the AoC and popularity among competitive programming,\nC++ might be also a very good choice. Only if you are familiar with it, I guess…

      \n

      If you want a challenge, you might also choose to rotate the languages each day.\nThough I prefer to use only one language.

      \n

      For this year I have been deciding between Rust, C++ and Pascal or Ada.

      \n

      I have tried Rust last year and have survived with it for 3 days and then gave\nup and switched to Kotlin, which was pretty good given it is “Java undercover”.\nI pretty much like the ideas behind Rust, I am not sure about the whole cult and\nimplementation of those ideas though. After some years with C/C++, I would say\nthat Rust feels too safe for my taste and tries to “punish me” even for the\nmost trivial things.

      \n

      C++ is a very robust, but also comes with a wide variety of options providing you\nthe ability to shoot yourself in the leg. I have tried to solve few days of previous\nAdvent of Code events, it was relatively easy to solve the problems in C++, given\nthat I do not admit writing my own iterator for enumerate

      \n

      Pascal or Ada were meme choices :) Ada is heavily inspired by Pascal and has a\npretty nice standard library that offers enough to be able to quickly solve some\nproblems in it. However the toolkit is questionable :/

      \n

      Choosing libraries

      \n

      Preparations for Rust

      \n

      All of the sources, later on including solutions, can be found at my\nGitLab.

      \n

      Toolkit

      \n

      Since we are using Rust, we are going to use a Cargo and more than likely VSCode\nwith rust-analyzer. Because of my choice of libraries, we will also introduce\na .envrc file that can be used by direnv, which allows you to set specific\nenvironment variables when you enter a directory. In our case, we will use

      \n
      # to show nice backtrace when using the color-eyre
      export RUST_BACKTRACE=1

      # to catch logs generated by tracing
      export RUST_LOG=trace
      \n

      And for the one of the most obnoxious things ever, we will use a script to download\nthe inputs instead of “clicking, opening and copying to a file1. There is\nno need to be fancy, so we will adjust Python script by Martin2.

      \n
      #!/usr/bin/env python3

      import datetime
      import yaml
      import requests
      import sys


      def load_config():
      with open(\"env.yaml\", \"r\") as f:
      js = yaml.load(f, Loader=yaml.Loader)
      return js[\"session\"], js[\"year\"]


      def get_input(session, year, day):
      return requests.get(
      f\"https://adventofcode.com/{year}/day/{day}/input\",
      cookies={\"session\": session},
      headers={
      \"User-Agent\": \"{repo} by {mail}\".format(
      repo=\"gitlab.com/mfocko/advent-of-code-2022\",
      mail=\"me@mfocko.xyz\",
      )
      },
      ).content.decode(\"utf-8\")


      def main():
      day = datetime.datetime.now().day
      if len(sys.argv) == 2:
      day = sys.argv[1]

      session, year = load_config()
      problem_input = get_input(session, year, day)

      with open(f\"./inputs/day{day:>02}.txt\", \"w\") as f:
      f.write(problem_input)


      if __name__ == \"__main__\":
      main()
      \n

      If the script is called without any arguments, it will deduce the day from the\nsystem, so we do not need to change the day every morning. It also requires a\nconfiguration file:

      \n
      # env.yaml
      session: ‹your session cookie›
      year: 2022
      \n

      Libraries

      \n

      Looking at the list of the libraries, I have chosen “a lot” of them. Let's walk\nthrough each of them.

      \n

      tracing and tracing-subscriber are the crates that can be used for tracing\nand logging of your Rust programs, there are also other crates that can help you\nwith providing backtrace to the Sentry in case you have deployed your application\nsomewhere and you want to watch over it. In our use case we will just utilize the\nmacros for debugging in the terminal.

      \n

      thiserror, anyhow and color-eyre are used for error reporting.\nthiserror is a very good choice for libraries, cause it extends the Error\nfrom the std and allows you to create more convenient error types. Next is\nanyhow which kinda builds on top of the thiserror and provides you with simpler\nerror handling in binaries3. And finally we have color-eyre which, as I found\nout later, is a colorful (wink wink) extension of eyre which is fork of anyhow\nwhile supporting customized reports.

      \n

      In the end I have decided to remove thiserror and anyhow, since first one is\nsuitable for libraries and the latter was basically fully replaced by {color-,}eyre.

      \n

      regex and lazy_static are a very good and also, I hope, self-explanatory\ncombination. lazy_static allows you to have static variables that must be initialized\nduring runtime.

      \n

      itertools provides some nice extensions to the iterators from the std.

      \n

      My own “library”

      \n

      When creating the crate for this year's Advent of Code, I have chosen a library\ntype. Even though standard library is huge, some things might not be included and\nalso we can follow KISS. I have 2 modules that my “library” exports, one for\nparsing and one for 2D vector (that gets used quite often during Advent of Code).

      \n

      Key part is, of course, processing the input and my library exports following\nfunctions that get used a lot:

      \n
      /// Reads file to the string.
      pub fn file_to_string<P: AsRef<Path>>(pathname: P) -> String;

      /// Reads file and returns it as a vector of characters.
      pub fn file_to_chars<P: AsRef<Path>>(pathname: P) -> Vec<char>;

      /// Reads file and returns a vector of parsed structures. Expects each structure
      /// on its own line in the file. And `T` needs to implement `FromStr` trait.
      pub fn file_to_structs<P: AsRef<Path>, T: FromStr>(pathname: P) -> Vec<T>
      where
      <T as FromStr>::Err: Debug;

      /// Converts iterator over strings to a vector of parsed structures. `T` needs
      /// to implement `FromStr` trait and its error must derive `Debug` trait.
      pub fn strings_to_structs<T: FromStr, U>(
      iter: impl Iterator<Item = U>
      ) -> Vec<T>
      where
      <T as std::str::FromStr>::Err: std::fmt::Debug,
      U: Deref<Target = str>;

      /// Reads file and returns it as a vector of its lines.
      pub fn file_to_lines<P: AsRef<Path>>(pathname: P) -> Vec<String>;
      \n

      As for the vector, I went with a rather simple implementation that allows only\naddition of the vectors for now and accessing the elements via functions x()\nand y(). Also the vector is generic, so we can use it with any numeric type we\nneed.

      \n

      Skeleton

      \n

      We can also prepare a template to quickly bootstrap each of the days. We know\nthat each puzzle has 2 parts, which means that we can start with 2 functions that\nwill solve them.

      \n
      fn part1(input: &Input) -> Output {
      todo!()
      }

      fn part2(input: &Input) -> Output {
      todo!()
      }
      \n

      Both functions take reference to the input and return some output (in majority\nof puzzles, it is the same type). todo!() can be used as a nice placeholder,\nit also causes a panic when reached and we could also provide some string with\nan explanation, e.g. todo!(\"part 1\"). We have not given functions a specific\ntype and to avoid as much copy-paste as possible, we will introduce type aliases.

      \n
      type Input = String;
      type Output = i32;
      \n
      tip

      This allows us to quickly adjust the types only in one place without the need to\ndo regex-replace or replace them manually.

      \n

      For each day we get a personalized input that is provided as a text file. Almost\nall the time, we would like to get some structured type out of that input, and\ntherefore it makes sense to introduce a new function that will provide the parsing\nof the input.

      \n
      fn parse_input(path: &str) -> Input {
      todo!()
      }
      \n

      This “parser” will take a path to the file, just in case we would like to run the\nsample instead of input.

      \n

      OK, so now we can write a main function that will take all of the pieces and\nrun them.

      \n
      fn main() {
      let input = parse_input(\"inputs/dayXX.txt\");

      println!(\"Part 1: {}\", part_1(&input));
      println!(\"Part 2: {}\", part_2(&input));
      }
      \n

      This would definitely do :) But we have installed a few libraries and we want to\nuse them. In this part we are going to utilize tracing (for tracing, duh…)\nand color-eyre (for better error reporting, e.g. from parsing).

      \n
      fn main() -> Result<()> {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = parse_input(\"inputs/dayXX.txt\");

      info!(\"Part 1: {}\", part_1(&input));
      info!(\"Part 2: {}\", part_2(&input));

      Ok(())
      }
      \n

      The first statement will set up tracing and configure it to print out the logs to\nterminal, based on the environment variable. We also change the formatting a bit,\nsince we do not need all the fancy features of the logger. Pure initialization\nwould get us logs like this:

      \n
      2022-12-11T19:53:19.975343Z  INFO day01: Part 1: 0
      \n

      However after running that command, we will get the following:

      \n
       INFO src/bin/day01.rs:35: Part 1: 0
      \n

      And the color_eyre::install()? is quite straightforward. We just initialize the\nerror reporting by color eyre.

      \n
      caution

      Notice that we had to add Ok(()) to the end of the function and adjust the\nreturn type of the main to Result<()>. It is caused by the color eyre that\ncan be installed only once and therefore it can fail, that is how we got the ?\nat the end of the ::install which unwraps the »result« of the installation.

      \n

      Overall we will get to a template like this:

      \n
      use aoc_2022::*;

      use color_eyre::eyre::Result;
      use tracing::info;
      use tracing_subscriber::EnvFilter;

      type Input = String;
      type Output = i32;

      fn parse_input(path: &str) -> Input {
      todo!()
      }

      fn part1(input: &Input) -> Output {
      todo!()
      }

      fn part2(input: &Input) -> Output {
      todo!()
      }

      fn main() -> Result<()> {
      tracing_subscriber::fmt()
      .with_env_filter(EnvFilter::from_default_env())
      .with_target(false)
      .with_file(true)
      .with_line_number(true)
      .without_time()
      .compact()
      .init();
      color_eyre::install()?;

      let input = parse_input(\"inputs/dayXX.txt\");

      info!(\"Part 1: {}\", part_1(&input));
      info!(\"Part 2: {}\", part_2(&input));

      Ok(())
      }
      \n

      Footnotes

      \n
        \n
      1. \n

        Copy-pasting might be a relaxing thing to do, but you can also discover\nnasty stuff about your PC. See this Reddit post and the comment.

        \n
      2. \n
      3. \n

        GitHub profile

        \n
      4. \n
      5. \n

        Even though you can use it even for libraries, but handling errors from\nlibraries using anyhow is nasty… You will be the stinky one ;)

        \n
      6. \n
      \n
      ", "url": "https://blog.mfocko.xyz/blog/aoc-2022/intro", "title": "Advent of Code '22 in Rust", "summary": "Preparing for Advent of Code '22.", diff --git a/blog/index.html b/blog/index.html index fb37fe7..fae0165 100644 --- a/blog/index.html +++ b/blog/index.html @@ -14,8 +14,8 @@ - - + +
      - - + +

      Sort the matrix diagonally

      · 17 min read
      Matej Focko

      Let's try to solve one of the LeetCode challenges in easy and hard mode at the @@ -35,26 +35,26 @@ order and return the resulting matrix.

      Image describing the problem

      Skeleton and initial adjustments

      We are given the following skeleton for the C++ and the given challenge:

      -
      class Solution {
      public:
      vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {

      }
      };
      +
      class Solution {
      public:
      vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {

      }
      };

      The task is to sort the passed matrix diagonally and then return it. First of all, I don't like to solve this in a web browser, so we'll need to adjust it accordingly for running it locally. We'll start by including the vector header and using fully-qualified namespaces1 and also adding few tests:

      -
      #include <cassert>
      #include <vector>

      using matrix = std::vector<std::vector<int>>;

      class Solution {
      public:
      matrix diagonalSort(matrix& mat)
      {
      }
      };

      static void test_case_1()
      {
      // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
      // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
      std::vector { 2, 2, 1, 2 },
      std::vector { 1, 1, 1, 2 } })
      == std::vector { std::vector { 1, 1, 1, 1 },
      std::vector { 1, 2, 2, 2 },
      std::vector { 1, 2, 3, 3 } }));
      }

      static void test_case_2()
      {
      // Input: mat =
      // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
      // Output:
      // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
      std::vector { 23, 55, 17, 45, 15, 52 },
      std::vector { 75, 31, 36, 44, 58, 8 },
      std::vector { 22, 27, 33, 25, 68, 4 },
      std::vector { 84, 28, 14, 11, 5, 50 } })
      == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
      std::vector { 11, 11, 25, 45, 8, 69 },
      std::vector { 14, 23, 25, 44, 58, 15 },
      std::vector { 22, 27, 31, 36, 50, 66 },
      std::vector { 84, 28, 75, 33, 55, 68 } }));
      }

      int main()
      {
      test_case_1();
      test_case_2();

      return 0;
      }
      +
      #include <cassert>
      #include <vector>

      using matrix = std::vector<std::vector<int>>;

      class Solution {
      public:
      matrix diagonalSort(matrix& mat)
      {
      }
      };

      static void test_case_1()
      {
      // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
      // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
      std::vector { 2, 2, 1, 2 },
      std::vector { 1, 1, 1, 2 } })
      == std::vector { std::vector { 1, 1, 1, 1 },
      std::vector { 1, 2, 2, 2 },
      std::vector { 1, 2, 3, 3 } }));
      }

      static void test_case_2()
      {
      // Input: mat =
      // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
      // Output:
      // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
      std::vector { 23, 55, 17, 45, 15, 52 },
      std::vector { 75, 31, 36, 44, 58, 8 },
      std::vector { 22, 27, 33, 25, 68, 4 },
      std::vector { 84, 28, 14, 11, 5, 50 } })
      == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
      std::vector { 11, 11, 25, 45, 8, 69 },
      std::vector { 14, 23, 25, 44, 58, 15 },
      std::vector { 22, 27, 31, 36, 50, 66 },
      std::vector { 84, 28, 75, 33, 55, 68 } }));
      }

      int main()
      {
      test_case_1();
      test_case_2();

      return 0;
      }

      We need to return the matrix, but we're given a reference to the input matrix. We can easily abuse the C++ here and just switch the reference to value, this way the matrix will be copied when passed to the function, we can sort the copy and just return it back. And we also get yelled by the compiler for the fact that the method doesn't return anything yet, so to make it “shut up” we will just return the input for now:

      -
      -    matrix diagonalSort(matrix& mat)
      + matrix diagonalSort(matrix mat)
      {
      + return mat;
      }
      +
      -    matrix diagonalSort(matrix& mat)
      + matrix diagonalSort(matrix mat)
      {
      + return mat;
      }

      Now, we get the copy and we're good to go.

      Naïve solution

      As you may know, C++ offers a plethora of functions that can be used to your advantage, given that you know how to “bend” the data structures accordingly.

      What does that mean for us? Well, we have an std::sort, we can use it, right? Let's have a look at it:

      -
      template< class RandomIt >
      void sort( RandomIt first, RandomIt last );
      +
      template< class RandomIt >
      void sort( RandomIt first, RandomIt last );

      This overload is more than we need. What does it do? It just sorts the elements in the range [first, last) using operator< on them. We can't sort the whole matrix using this, but… we can sort just »one« diagonal without doing much work @@ -72,10 +72,10 @@ up, i.e. “compiler-assisted development3. And that way we get

      -
      matrix diagonalSort(matrix mat)
      {
      // we iterate over the diagonals
      for (auto d : diagonals(mat)) {
      // and we sort each diagonal
      std::sort(d.begin(), d.end());
      }

      // we take the matrix by copy, so we can sort in-situ and return the copy
      // that we sorted
      return mat;
      }
      +
      matrix diagonalSort(matrix mat)
      {
      // we iterate over the diagonals
      for (auto d : diagonals(mat)) {
      // and we sort each diagonal
      std::sort(d.begin(), d.end());
      }

      // we take the matrix by copy, so we can sort in-situ and return the copy
      // that we sorted
      return mat;
      }

      This solution looks very simple, doesn't it? Well, cause it is. Let's try compiling it:

      -
      matrix-sort.cpp:11:23: error: use of undeclared identifier 'diagonals' [clang-diagnostic-error]
      for (auto d : diagonals(mat)) {
      ^
      Found compiler error(s).
      make: *** [makefile:14: tidy] Error 1
      +
      matrix-sort.cpp:11:23: error: use of undeclared identifier 'diagonals' [clang-diagnostic-error]
      for (auto d : diagonals(mat)) {
      ^
      Found compiler error(s).
      make: *** [makefile:14: tidy] Error 1

      OK, seems about right. We haven't implemented the diagonals yet. And based on what we've written so far, we need a function or a class diagonals that will give us the diagonals we need.

      @@ -90,7 +90,7 @@ do such functionality for a matrix of any type, not just the int fr
    2. get the beginning
    3. get the end (the “sentinel”)
    4. -
      template <typename T>
      class diagonals {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& _matrix;

      public:
      diagonals(matrix_t& m)
      : _matrix(m)
      {
      }
      diagonals_iter begin()
      {
      /* TODO */
      }
      diagonals_iter end()
      {
      /* TODO */
      }
      };
      +
      template <typename T>
      class diagonals {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& _matrix;

      public:
      diagonals(matrix_t& m)
      : _matrix(m)
      {
      }
      diagonals_iter begin()
      {
      /* TODO */
      }
      diagonals_iter end()
      {
      /* TODO */
      }
      };

      Now we have a diagonals that we can use to go through the diagonals. We haven't implemented the core of it yet. Let's go through what we have for now.

      We have a templated class with templated T that is used as a placeholder for any @@ -109,7 +109,7 @@ in the first row, followed by the rest of the diagonals in the first column.

      need to know which diagonal is next. For that purpose we will pass the indices of the first cell on the diagonal. That way we can always tell how to move forward.

      We will start by updating the begin and end to reflect our choice accordingly.

      -
      diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
      diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }
      +
      diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
      diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }

      For the begin we return the first diagonal that starts at (0, 0). And because we have decided to do the diagonals in the first column at the end, the first diagonal that is not a valid one is the one at (0, height). Apart from the @@ -123,7 +123,7 @@ don't care about the fact they don't need to be sorted.

      We can start with a simple skeleton based on the information that we pass from the diagonals. Also to utilize the matrix_t and also contain implementation details hidden away, we will put this code into the diagonals class.

      -
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }
      };
      +
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }
      };

      In this case we will be implementing a “simple” forward iterator, so we don't need to implement a lot. Notably it will be:

        @@ -133,12 +133,12 @@ iterate over)
      • dereference operator (we need to be able to retrieve the objects we iterate over)
      -
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator!=(const diagonals_iter& rhs) const
      {
      // iterators are not equal if they reference different matrices, or
      // their positions differ
      return m != rhs.m || x != rhs.x || y != rhs.y;
      }

      diagonals_iter& operator++()
      {
      if (y != 0) {
      // iterating through diagonals down the first column
      y++;
      return *this;
      }

      // iterating the diagonals along the first row
      x++;
      if (x == m.front().size()) {
      // switching to diagonals in the first column
      x = 0;
      y++;
      }

      return *this;
      }

      diagonal<T> operator*() const { return diagonal { m, x, y }; }
      };
      +
      class diagonals_iter {
      matrix_t& m;
      std::size_t x;
      std::size_t y;

      public:
      diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator!=(const diagonals_iter& rhs) const
      {
      // iterators are not equal if they reference different matrices, or
      // their positions differ
      return m != rhs.m || x != rhs.x || y != rhs.y;
      }

      diagonals_iter& operator++()
      {
      if (y != 0) {
      // iterating through diagonals down the first column
      y++;
      return *this;
      }

      // iterating the diagonals along the first row
      x++;
      if (x == m.front().size()) {
      // switching to diagonals in the first column
      x = 0;
      y++;
      }

      return *this;
      }

      diagonal<T> operator*() const { return diagonal { m, x, y }; }
      };

      Let's go one-by-one. Inequality operator is rather simple, just compare iterator's attributes field-by-field. If you think about it, checking inequality of two 2D vectors may be a bit inefficient, therefore, we can swap around and check it as a last thing.

      -
      -        return m != rhs.m || x != rhs.x || y != rhs.y;
      + return x != rhs.x || y != rhs.y || m != rhs.m;
      +
      -        return m != rhs.m || x != rhs.x || y != rhs.y;
      + return x != rhs.x || y != rhs.y || m != rhs.m;

      Preincrementation is where the magic happens. If you have a better look, you can see two branches of this operation:

        @@ -158,7 +158,7 @@ something else. In our case it will be a class called diagonal.

        a diagonal is the matrix itself and the “start” of the diagonal (row and column). And we also know that the diagonal must provide some iterators for the std::sort function. We can start with the following skeleton:

        -
        template <typename T>
        class diagonal {
        using matrix_t = std::vector<std::vector<T>>;

        matrix_t& matrix;
        std::size_t x;
        std::size_t y;

        public:
        diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
        : matrix(matrix)
        , x(x)
        , y(y)
        {
        }

        diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }

        diagonal_iter end() const
        {
        auto max_x = matrix[y].size();
        auto max_y = matrix.size();

        // we need to find the distance in which we get out of bounds (either in
        // column or row)
        auto steps = std::min(max_x - x, max_y - y);

        return diagonal_iter { matrix, x + steps, y + steps };
        }
        };
        +
        template <typename T>
        class diagonal {
        using matrix_t = std::vector<std::vector<T>>;

        matrix_t& matrix;
        std::size_t x;
        std::size_t y;

        public:
        diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
        : matrix(matrix)
        , x(x)
        , y(y)
        {
        }

        diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }

        diagonal_iter end() const
        {
        auto max_x = matrix[y].size();
        auto max_y = matrix.size();

        // we need to find the distance in which we get out of bounds (either in
        // column or row)
        auto steps = std::min(max_x - x, max_y - y);

        return diagonal_iter { matrix, x + steps, y + steps };
        }
        };

        Initialization is rather simple, we just “keep” the stuff we get, begin is the simplest, we just delegate.

        In case of the end, it gets more complicated. We need to know where is the “end” @@ -185,7 +185,7 @@ be used in std::sort. We need the usual operations like:

        We will also add all the types that our iterator uses with the category of the iterator, i.e. what interface it supports:

        -
        class diagonal_iter {
        // we need to keep reference to the matrix itself
        matrix_t& m;

        // we need to be able to tell our current position
        std::size_t x;
        std::size_t y;

        public:
        using difference_type = std::ptrdiff_t;
        using value_type = T;
        using pointer = T*;
        using reference = T&;
        using iterator_category = std::random_access_iterator_tag;

        diagonal_iter(matrix_t& matrix,
        std::size_t x,
        std::size_t y)
        : m(matrix)
        , x(x)
        , y(y)
        {
        }

        bool operator==(const diagonal_iter& rhs) const
        {
        return x == rhs.x && y == rhs.y && m == rhs.m;
        }

        diagonal_iter& operator++()
        {
        // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
        // the same time
        x++;
        y++;
        return *this;
        }

        reference operator*() const { return m[y][x]; }
        };
        +
        class diagonal_iter {
        // we need to keep reference to the matrix itself
        matrix_t& m;

        // we need to be able to tell our current position
        std::size_t x;
        std::size_t y;

        public:
        using difference_type = std::ptrdiff_t;
        using value_type = T;
        using pointer = T*;
        using reference = T&;
        using iterator_category = std::random_access_iterator_tag;

        diagonal_iter(matrix_t& matrix,
        std::size_t x,
        std::size_t y)
        : m(matrix)
        , x(x)
        , y(y)
        {
        }

        bool operator==(const diagonal_iter& rhs) const
        {
        return x == rhs.x && y == rhs.y && m == rhs.m;
        }

        diagonal_iter& operator++()
        {
        // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
        // the same time
        x++;
        y++;
        return *this;
        }

        reference operator*() const { return m[y][x]; }
        };

        This is pretty similar to the previous iterator, but now we need to implement the remaining requirements of the random access iterator. Let's see what those are:

          @@ -196,16 +196,16 @@ remaining requirements of the random access iterator. Let's see wh
        • define an ordering on the iterators

        Let's fill them in:

        -
        class diagonal_iter {
        // we need to keep reference to the matrix itself
        matrix_t& m;

        // we need to be able to tell our current position
        std::size_t x;
        std::size_t y;

        public:
        using difference_type = std::ptrdiff_t;
        using value_type = T;
        using pointer = T*;
        using reference = T&;
        using iterator_category = std::random_access_iterator_tag;

        diagonal_iter(matrix_t& matrix,
        std::size_t x,
        std::size_t y)
        : m(matrix)
        , x(x)
        , y(y)
        {
        }

        bool operator==(const diagonal_iter& rhs) const
        {
        return x == rhs.x && y == rhs.y && m == rhs.m;
        }

        diagonal_iter& operator++()
        {
        // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
        // the same time
        x++;
        y++;
        return *this;
        }

        reference operator*() const { return m[y][x]; }

        // exactly opposite to the incrementation
        diagonal_iter operator--()
        {
        x--;
        y--;
        return *this;
        }

        // moving ‹n› steps back is same as calling decrementation ‹n›-times, so we
        // can just return a new iterator and subtract ‹n› from both coordinates in
        // the matrix
        diagonal_iter operator-(difference_type n) const
        {
        return diagonal_iter { m, x - n, y - n };
        }

        // here we assume that we are given two iterators on the same diagonal
        difference_type operator-(const diagonal_iter& rhs) const
        {
        assert(m == rhs.m);
        return x - rhs.x;
        }

        // counterpart of moving ‹n› steps backwards
        diagonal_iter operator+(difference_type n) const
        {
        return diagonal_iter { m, x + n, y + n };
        }

        // we compare the coordinates, and also assume that those 2 iterators are
        // lying on the same diagonal
        bool operator<(const diagonal_iter& rhs) const
        {
        assert(m == rhs.m);
        return x < rhs.x && y < rhs.y;
        }
        };
        +
        class diagonal_iter {
        // we need to keep reference to the matrix itself
        matrix_t& m;

        // we need to be able to tell our current position
        std::size_t x;
        std::size_t y;

        public:
        using difference_type = std::ptrdiff_t;
        using value_type = T;
        using pointer = T*;
        using reference = T&;
        using iterator_category = std::random_access_iterator_tag;

        diagonal_iter(matrix_t& matrix,
        std::size_t x,
        std::size_t y)
        : m(matrix)
        , x(x)
        , y(y)
        {
        }

        bool operator==(const diagonal_iter& rhs) const
        {
        return x == rhs.x && y == rhs.y && m == rhs.m;
        }

        diagonal_iter& operator++()
        {
        // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
        // the same time
        x++;
        y++;
        return *this;
        }

        reference operator*() const { return m[y][x]; }

        // exactly opposite to the incrementation
        diagonal_iter operator--()
        {
        x--;
        y--;
        return *this;
        }

        // moving ‹n› steps back is same as calling decrementation ‹n›-times, so we
        // can just return a new iterator and subtract ‹n› from both coordinates in
        // the matrix
        diagonal_iter operator-(difference_type n) const
        {
        return diagonal_iter { m, x - n, y - n };
        }

        // here we assume that we are given two iterators on the same diagonal
        difference_type operator-(const diagonal_iter& rhs) const
        {
        assert(m == rhs.m);
        return x - rhs.x;
        }

        // counterpart of moving ‹n› steps backwards
        diagonal_iter operator+(difference_type n) const
        {
        return diagonal_iter { m, x + n, y + n };
        }

        // we compare the coordinates, and also assume that those 2 iterators are
        // lying on the same diagonal
        bool operator<(const diagonal_iter& rhs) const
        {
        assert(m == rhs.m);
        return x < rhs.x && y < rhs.y;
        }
        };

        At this point we could probably try and compile it, right? If we do so, we will get yelled at by a compiler for the following reasons:

        -
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
        __last = __next;
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization 'std::__unguarded_linear_insert<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>' requested here
        std::__unguarded_linear_insert(__i,
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization 'std::__insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__final_insertion_sort(__first, __last, __comp);
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
        ^
        matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
        std::sort(d.begin(), d.end());
        ^
        matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
        matrix_t& m;
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to '__unguarded_linear_insert' [clang-diagnostic-error]
        std::__unguarded_linear_insert(__i,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization 'std::__unguarded_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__final_insertion_sort(__first, __last, __comp);
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
        ^
        matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
        std::sort(d.begin(), d.end());
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal<int>::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]
        __unguarded_linear_insert(_RandomAccessIterator __last,
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
        __last = __cut;
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization 'std::__introsort_loop<diagonal<int>::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__introsort_loop(__first, __last,
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
        ^
        matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
        std::sort(d.begin(), d.end());
        ^
        matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
        matrix_t& m;
        ^
        +
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
        __last = __next;
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization 'std::__unguarded_linear_insert<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>' requested here
        std::__unguarded_linear_insert(__i,
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization 'std::__insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__final_insertion_sort(__first, __last, __comp);
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
        ^
        matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
        std::sort(d.begin(), d.end());
        ^
        matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
        matrix_t& m;
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to '__unguarded_linear_insert' [clang-diagnostic-error]
        std::__unguarded_linear_insert(__i,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization 'std::__unguarded_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__final_insertion_sort(__first, __last, __comp);
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
        ^
        matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
        std::sort(d.begin(), d.end());
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal<int>::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]
        __unguarded_linear_insert(_RandomAccessIterator __last,
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
        __last = __cut;
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization 'std::__introsort_loop<diagonal<int>::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__introsort_loop(__first, __last,
        ^
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
        std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
        ^
        matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
        std::sort(d.begin(), d.end());
        ^
        matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
        matrix_t& m;
        ^

        That's a lot of noise, isn't it? Let's focus on the important parts:

        -
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]

        matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
        matrix_t& m;
        ^
        +
        /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]

        matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
        matrix_t& m;
        ^

        Ah! We have a reference in our iterator, and this prevents us from having a copy assignment operator (that is used “somewhere” in the sorting algorithm). Well… Let's just wrap it!

        -
        # we need to keep a different type than reference
        - matrix_t& m;
        + std::reference_wrapper<matrix_t> m;

        # in comparison we need to get the reference out of the wrapper first
        - return x == rhs.x && y == rhs.y && m == rhs.m;
        + return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();

        # same when we return a reference to the “cell” in the matrix
        - reference operator*() const { return m[y][x]; }
        + reference operator*() const { return m.get()[y][x]; }

        # and finally in the assertions that we set for the “distance” and “less than”
        - assert(m == rhs.m);
        + assert(m.get() == rhs.m.get());
        +
        # we need to keep a different type than reference
        - matrix_t& m;
        + std::reference_wrapper<matrix_t> m;

        # in comparison we need to get the reference out of the wrapper first
        - return x == rhs.x && y == rhs.y && m == rhs.m;
        + return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();

        # same when we return a reference to the “cell” in the matrix
        - reference operator*() const { return m[y][x]; }
        + reference operator*() const { return m.get()[y][x]; }

        # and finally in the assertions that we set for the “distance” and “less than”
        - assert(m == rhs.m);
        + assert(m.get() == rhs.m.get());

        We're done now! We have written an iterator over diagonals for a 2D vector. You can have a look at the final result here.

        Footnotes

          diff --git a/blog/rss.xml b/blog/rss.xml index 247d2e7..06de88d 100644 --- a/blog/rss.xml +++ b/blog/rss.xml @@ -79,7 +79,7 @@ will make people dull and they should think about it anyways, that's ho issue above has been discovered. If everyone walked past and didn't think about it, no one would discover this issue till it bit them hard.

          Standard library

          Even the standard library is littered with unsafe blocks that are prefixed -with comments in style:

          // SAFETY: …

          The fact that the casual Rust dev doesn't have to think much about safety, +with comments in style:

          // SAFETY: …

          The fact that the casual Rust dev doesn't have to think much about safety, cause the compiler has their back, doesn't mean that the Rust compiler dev doesn't either.

          I gotta admit that I adopted this concept in other languages (even in Python), cause you can encounter situations where it doesn't have to be clear why you @@ -101,7 +101,7 @@ as the Rust one.

          One of the other negatives is the introduction of bugs. If you're pushing changes, somewhat mindlessly, at such a fast pace, it is inevitable to introduce a bunch bugs in the process. Checking the GitHub issue tracker with

          -
          is:issue is:open label:C-bug label:T-compiler
          +
          is:issue is:open label:C-bug label:T-compiler

          yields 2,224 open issues at the time of writing this post.

          RFCs

          You can find a lot of RFCs for the Rust. Some of them are more questionable @@ -109,13 +109,13 @@ than the others. Fun thing is that a lot of them make it to the nightly builds, so they can be tested and polished off. Even the questionable ones… I'll leave few examples for a better understanding.

          One of such features is the do yeet expression:

          -
          #![feature(yeet_expr)]

          fn foo() -> Result<String, i32> {
          do yeet 4;
          }
          assert_eq!(foo(), Err(4));

          fn bar() -> Option<String> {
          do yeet;
          }
          assert_eq!(bar(), None);
          +
          #![feature(yeet_expr)]

          fn foo() -> Result<String, i32> {
          do yeet 4;
          }
          assert_eq!(foo(), Err(4));

          fn bar() -> Option<String> {
          do yeet;
          }
          assert_eq!(bar(), None);

          It allows you to “yeet” the errors out of the functions that return Result or Option.

          One of the more recent ones is the ability to include Cargo manifests into the sources, so you can do something like:

          -
          #!/usr/bin/env cargo
          ---
          [dependencies]
          clap = { version = "4.2", features = ["derive"] }
          ---

          use clap::Parser;

          #[derive(Parser, Debug)]
          #[clap(version)]
          struct Args {
          #[clap(short, long, help = "Path to config")]
          config: Option<std::path::PathBuf>,
          }

          fn main() {
          let args = Args::parse();
          println!("{:?}", args);
          }
          +
          #!/usr/bin/env cargo
          ---
          [dependencies]
          clap = { version = "4.2", features = ["derive"] }
          ---

          use clap::Parser;

          #[derive(Parser, Debug)]
          #[clap(version)]
          struct Args {
          #[clap(short, long, help = "Path to config")]
          config: Option<std::path::PathBuf>,
          }

          fn main() {
          let args = Args::parse();
          println!("{:?}", args);
          }

          I would say you can get almost anything into the language…

          Community and hype train

          Rust community is a rather unique thing. A lot of people will hate me for this, @@ -191,10 +191,10 @@ have to admit it's much easier to remember the bad stuff as opposed to the good.

          I prefered using Rust for the Advent of Code and Codeforces as it provides a rather easy way to test the solutions before running them with the challenge input (or test runner). I can give an example from the Advent of Code:

          -
          use aoc_2023::*;

          type Output1 = i32;
          type Output2 = Output1;

          struct DayXX {}
          impl Solution<Output1, Output2> for DayXX {
          fn new<P: AsRef<Path>>(pathname: P) -> Self {
          let lines: Vec<String> = file_to_lines(pathname);

          todo!()
          }

          fn part_1(&mut self) -> Output1 {
          todo!()
          }

          fn part_2(&mut self) -> Output2 {
          todo!()
          }
          }

          fn main() -> Result<()> {
          DayXX::main()
          }

          test_sample!(day_XX, DayXX, 42, 69);
          +
          use aoc_2023::*;

          type Output1 = i32;
          type Output2 = Output1;

          struct DayXX {}
          impl Solution<Output1, Output2> for DayXX {
          fn new<P: AsRef<Path>>(pathname: P) -> Self {
          let lines: Vec<String> = file_to_lines(pathname);

          todo!()
          }

          fn part_1(&mut self) -> Output1 {
          todo!()
          }

          fn part_2(&mut self) -> Output2 {
          todo!()
          }
          }

          fn main() -> Result<()> {
          DayXX::main()
          }

          test_sample!(day_XX, DayXX, 42, 69);

          This was the skeleton I've used and the macro at the end is my own creation that expands to:

          -
          #[cfg(test)]
          mod day_XX {
          use super::*;

          #[test]
          fn part_1() {
          let path = DayXX::get_sample(1);
          let mut day = DayXX::new(path);
          assert_eq!(day.part_1(), 42);
          }

          #[test]
          fn part_2() {
          let path = DayXX::get_sample(2);
          let mut day = DayXX::new(path);
          assert_eq!(day.part_2(), 69);
          }
          }
          +
          #[cfg(test)]
          mod day_XX {
          use super::*;

          #[test]
          fn part_1() {
          let path = DayXX::get_sample(1);
          let mut day = DayXX::new(path);
          assert_eq!(day.part_1(), 42);
          }

          #[test]
          fn part_2() {
          let path = DayXX::get_sample(2);
          let mut day = DayXX::new(path);
          assert_eq!(day.part_2(), 69);
          }
          }

          When you're solving the problem, all you need to do is switch between cargo test and cargo run to check the answer to either sample or the challenge input itself.

          @@ -219,7 +219,7 @@ language is a good habit, as I've mentioned above. You should be able to argue why you can do something safely, even if the compiler is not kicking your ass because of it.

          Excerpt of such comment from work:

          -
          # SAFETY: Taking first package instead of specific package should be
          # safe, since we have put a requirement on »one« ‹upstream_project_url›
          # per Packit config, i.e. even if we're dealing with a monorepo, there
          # is only »one« upstream. If there is one upstream, there is only one
          # set of GPG keys that can be allowed.
          return self.downstream_config.packages[
          self.downstream_config._first_package
          ].allowed_gpg_keys
          +
          # SAFETY: Taking first package instead of specific package should be
          # safe, since we have put a requirement on »one« ‹upstream_project_url›
          # per Packit config, i.e. even if we're dealing with a monorepo, there
          # is only »one« upstream. If there is one upstream, there is only one
          # set of GPG keys that can be allowed.
          return self.downstream_config.packages[
          self.downstream_config._first_package
          ].allowed_gpg_keys

          Traits

          One of the other things I like are the traits. They are more restrictive than templates or concepts in C++, but they're doing their job pretty good. If you @@ -228,12 +228,12 @@ of copy-paste, but that's soon to be fixed by the

      +order based on the complexity they can express:

      Rust's trait < Haskell's type class < C++'s concept

      You can also hit some issues, like me when trying to support conversions between underlying numeric types of a 2D vectors or support for using an operator from both sides (I couldn't get c * u to work in the same way as u * c because the first one requires you to implement the trait of a built-in type).

      -

    So in shell you would do

    -
    # dnf copr enable ‹copr-repository›
    # dnf install ‹package-from-the-repository›
    +
    # dnf copr enable ‹copr-repository›
    # dnf install ‹package-from-the-repository›

    And… that's it! Nothing else needed! Simple, right? And literally same process as you would do for the PPA.

    AUR

    On the other hand, if you are familiar with the archLinux, you definitely know @@ -396,17 +396,17 @@ each row and column to determine the boundaries, it was very easy to do for the rows (cause each row is a Vec element), but not for the columns, since they span multiple rows.

    For this use case I have implemented my own column iterator:

    -
    pub struct ColumnIterator<'a, T> {
    map: &'a [Vec<T>],
    column: usize,

    i: usize,
    }

    impl<'a, T> ColumnIterator<'a, T> {
    pub fn new(map: &'a [Vec<T>], column: usize) -> ColumnIterator<'a, T> {
    Self { map, column, i: 0 }
    }
    }

    impl<'a, T> Iterator for ColumnIterator<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
    if self.i >= self.map.len() {
    return None;
    }

    self.i += 1;
    Some(&self.map[self.i - 1][self.column])
    }
    }
    +
    pub struct ColumnIterator<'a, T> {
    map: &'a [Vec<T>],
    column: usize,

    i: usize,
    }

    impl<'a, T> ColumnIterator<'a, T> {
    pub fn new(map: &'a [Vec<T>], column: usize) -> ColumnIterator<'a, T> {
    Self { map, column, i: 0 }
    }
    }

    impl<'a, T> Iterator for ColumnIterator<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
    if self.i >= self.map.len() {
    return None;
    }

    self.i += 1;
    Some(&self.map[self.i - 1][self.column])
    }
    }

    Given this piece of an iterator, it is very easy to factor out the common functionality between the rows and columns into:

    -
    let mut find_boundaries = |constructor: fn(usize) -> Orientation,
    iterator: &mut dyn Iterator<Item = &char>,
    upper_bound,
    i| {
    let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == ' ');
    let start = first_non_empty.next().unwrap().0 as isize;

    let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
    let end = last_non_empty.next().unwrap_or((upper_bound, &'_')).0 as isize;

    boundaries.insert(constructor(i), start..end);
    };
    +
    let mut find_boundaries = |constructor: fn(usize) -> Orientation,
    iterator: &mut dyn Iterator<Item = &char>,
    upper_bound,
    i| {
    let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == ' ');
    let start = first_non_empty.next().unwrap().0 as isize;

    let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
    let end = last_non_empty.next().unwrap_or((upper_bound, &'_')).0 as isize;

    boundaries.insert(constructor(i), start..end);
    };

    And then use it as such:

    -
    // construct all horizontal boundaries
    (0..map.len()).for_each(|row| {
    find_boundaries(
    Orientation::horizontal,
    &mut map[row].iter(),
    map[row].len(),
    row,
    );
    });

    // construct all vertical boundaries
    (0..map[0].len()).for_each(|col| {
    find_boundaries(
    Orientation::vertical,
    &mut ColumnIterator::new(&map, col),
    map.len(),
    col,
    );
    });
    +
    // construct all horizontal boundaries
    (0..map.len()).for_each(|row| {
    find_boundaries(
    Orientation::horizontal,
    &mut map[row].iter(),
    map[row].len(),
    row,
    );
    });

    // construct all vertical boundaries
    (0..map[0].len()).for_each(|col| {
    find_boundaries(
    Orientation::vertical,
    &mut ColumnIterator::new(&map, col),
    map.len(),
    col,
    );
    });

    Walking around the map

    Once the 2nd part got introduced, you start to think about a way how not to copy-paste a lot of stuff (I haven't avoided it anyways…). In this problem, I've chosen to introduce a trait (i.e. interface) for 2D and 3D walker.

    -
    trait Wrap: Clone {
    type State;

    // simulation
    fn is_blocked(&self) -> bool;
    fn step(&mut self, steps: isize);
    fn turn_left(&mut self);
    fn turn_right(&mut self);

    // movement
    fn next(&self) -> (Self::State, Direction);

    // final answer
    fn answer(&self) -> Output;
    }
    +
    trait Wrap: Clone {
    type State;

    // simulation
    fn is_blocked(&self) -> bool;
    fn step(&mut self, steps: isize);
    fn turn_left(&mut self);
    fn turn_right(&mut self);

    // movement
    fn next(&self) -> (Self::State, Direction);

    // final answer
    fn answer(&self) -> Output;
    }

    Each walker maintains its own state and also provides the functions that are used during the simulation. The “promised” methods are separated into:

      @@ -418,7 +418,7 @@ implementation-specific walker

    Both 2D and 3D versions borrow the original input and therefore you must annotate the lifetime of it:

    -
    struct Wrap2D<'a> {
    input: &'a Input,
    position: Position,
    direction: Direction,
    }
    impl<'a> Wrap2D<'a> {
    fn new(input: &'a Input) -> Wrap2D<'a> {
    // …
    +
    struct Wrap2D<'a> {
    input: &'a Input,
    position: Position,
    direction: Direction,
    }
    impl<'a> Wrap2D<'a> {
    fn new(input: &'a Input) -> Wrap2D<'a> {
    // …

    Problems

    I have used a lot of closures for this problem and once I introduced a parameter that was of unknown type (apart from the fact it implements a specific trait), I @@ -435,13 +435,13 @@ of rather smart suggestions.

    char was the .is_digit() function that takes a radix as a parameter. Clippy noticed that I use radix = 10 and suggested switching to .is_ascii_digit() that does exactly the same thing:

    -
    -                .take_while(|c| c.is_digit(10))
    + .take_while(|c| c.is_ascii_digit())
    +
    -                .take_while(|c| c.is_digit(10))
    + .take_while(|c| c.is_ascii_digit())

    Another useful suggestion appeared when working with the iterators and I wanted to get the nn-th element from it. You know the .skip(), you know the .next(), just “slap” them together and we're done for 😁 Well, I got suggested to use .nth() that does exactly the combination of the two mentioned methods on iterators:

    -
    -            match it.clone().skip(skip).next().unwrap() {
    + match it.clone().nth(skip).unwrap() {
    +
    -            match it.clone().skip(skip).next().unwrap() {
    + match it.clone().nth(skip).unwrap() {

    Day 23: Unstable Diffusion

    tl;dr

    Simulating movement of elves around with a set of specific rules.

    Solution

    @@ -454,20 +454,20 @@ minimum that are, of course, exactly the same except for initial values and comparators, it looks like a rather simple fix, but typing in Rust is something else, right? In the end I settled for a function that computes both boundaries without any duplication while using a closure:

    -
    fn get_bounds(positions: &Input) -> (Vector2D<isize>, Vector2D<isize>) {
    let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {
    positions
    .iter()
    .fold(Vector2D::new(init, init), |acc, elf| {
    Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))
    })
    };

    (f(isize::MAX, &min::<isize>), f(isize::MIN, &max::<isize>))
    }
    +
    fn get_bounds(positions: &Input) -> (Vector2D<isize>, Vector2D<isize>) {
    let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {
    positions
    .iter()
    .fold(Vector2D::new(init, init), |acc, elf| {
    Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))
    })
    };

    (f(isize::MAX, &min::<isize>), f(isize::MIN, &max::<isize>))
    }

    This function returns a pair of 2D vectors that represent opposite points of the bounding rectangle of all elves.

    You might ask why would we need a closure and the answer is that positions cannot be captured from within the nested function, only via closure. One more fun fact on top of that is the type of the comparator

    -
    &dyn Fn(isize, isize) -> isize
    +
    &dyn Fn(isize, isize) -> isize

    Once we remove the dyn keyword, compiler yells at us and also includes a way how to get a more thorough explanation of the error by running

    $ rustc --explain E0782

    which shows us

    Trait objects must include the dyn keyword.

    Erroneous code example:

    -
    trait Foo {}
    fn test(arg: Box<Foo>) {} // error!
    +
    trait Foo {}
    fn test(arg: Box<Foo>) {} // error!

    Trait objects are a way to call methods on types that are not known until runtime but conform to some trait.

    Trait objects should be formed with Box<dyn Foo>, but in the code above @@ -475,7 +475,7 @@ runtime but conform to some trait.

    This makes it harder to see that arg is a trait object and not a simply a heap allocated type called Foo.

    To fix this issue, add dyn before the trait name.

    -
    trait Foo {}
    fn test(arg: Box<dyn Foo>) {} // ok!
    +
    trait Foo {}
    fn test(arg: Box<dyn Foo>) {} // ok!

    This used to be allowed before edition 2021, but is now an error.

    Rant

    Not all of the explanations are helpful though, in some cases they might be even more confusing than helpful, since they address very simple use cases.

    As you can see, even in this case there are two sides to the explanations:

      @@ -518,7 +518,7 @@ cleaned it up a bit. The changed version is shown here and the original was just more verbose.

    I'll skip the boring parts of checking bounds and entry/exit of the basin 😉 We can easily calculate positions of the blizzards using a modular arithmetics:

    -
    impl Index<Position> for Basin {
    type Output = char;

    fn index(&self, index: Position) -> &Self::Output {
    // ‹skipped boring parts›

    // We need to account for the loops of the blizzards
    let width = self.cols - 2;
    let height = self.rows - 2;

    let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;
    [
    (
    index.y() as usize,
    blizzard_origin(width, -1, index.z(), index.x()),
    '>',
    ),
    (
    index.y() as usize,
    blizzard_origin(width, 1, index.z(), index.x()),
    '<',
    ),
    (
    blizzard_origin(height, -1, index.z(), index.y()),
    index.x() as usize,
    'v',
    ),
    (
    blizzard_origin(height, 1, index.z(), index.y()),
    index.x() as usize,
    '^',
    ),
    ]
    .iter()
    .find_map(|&(y, x, direction)| {
    if self.map[y][x] == direction {
    Some(&self.map[y][x])
    } else {
    None
    }
    })
    .unwrap_or(&'.')
    }
    }
    +
    impl Index<Position> for Basin {
    type Output = char;

    fn index(&self, index: Position) -> &Self::Output {
    // ‹skipped boring parts›

    // We need to account for the loops of the blizzards
    let width = self.cols - 2;
    let height = self.rows - 2;

    let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;
    [
    (
    index.y() as usize,
    blizzard_origin(width, -1, index.z(), index.x()),
    '>',
    ),
    (
    index.y() as usize,
    blizzard_origin(width, 1, index.z(), index.x()),
    '<',
    ),
    (
    blizzard_origin(height, -1, index.z(), index.y()),
    index.x() as usize,
    'v',
    ),
    (
    blizzard_origin(height, 1, index.z(), index.y()),
    index.x() as usize,
    '^',
    ),
    ]
    .iter()
    .find_map(|&(y, x, direction)| {
    if self.map[y][x] == direction {
    Some(&self.map[y][x])
    } else {
    None
    }
    })
    .unwrap_or(&'.')
    }
    }

    As you can see, there is an expression for calculating the original position and it's used multiple times, so why not take it out to a lambda, right? 😉

    I couldn't get the rustfmt to format the for-loop nicely, so I've just @@ -536,10 +536,10 @@ algorithm, since it better reflects the cost function.

    a priority for the queue.

    Whereas with the A*, I have chosen to use both time and Manhattan distance that promotes vertices closer to the exit and with a minimum time taken.

    Cost function is, of course, a closure 😉

    -
    let cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());
    +
    let cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());

    And also for checking the possible moves from the current vertex, I have implemented, yet another, closure that yields an iterator with the next moves:

    -
    let next_positions = |p| {
    [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]
    .iter()
    .filter_map(move |&(x, y, t)| {
    let next_p = p + Vector3D::new(x, y, t);

    if basin[next_p] == '.' {
    Some(next_p)
    } else {
    None
    }
    })
    };
    +
    let next_positions = |p| {
    [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]
    .iter()
    .filter_map(move |&(x, y, t)| {
    let next_p = p + Vector3D::new(x, y, t);

    if basin[next_p] == '.' {
    Some(next_p)
    } else {
    None
    }
    })
    };

    Min-heap

    In this case I had a need to use the priority queue taking the elements with the lowest cost as the prioritized ones. Rust only offers you the BinaryHeap and @@ -549,7 +549,7 @@ the BinaryHeap). However the wrapping affects the type of the h popping the most prioritized elements yields values wrapped in the Reverse.

    For this purpose I have just taken the max-heap and wrapped it as a whole in a separate structure providing just the desired methods:

    -
    use std::cmp::{Ord, Reverse};
    use std::collections::BinaryHeap;

    pub struct MinHeap<T> {
    heap: BinaryHeap<Reverse<T>>,
    }

    impl<T: Ord> MinHeap<T> {
    pub fn new() -> MinHeap<T> {
    MinHeap {
    heap: BinaryHeap::new(),
    }
    }

    pub fn push(&mut self, item: T) {
    self.heap.push(Reverse(item))
    }

    pub fn pop(&mut self) -> Option<T> {
    self.heap.pop().map(|Reverse(x)| x)
    }
    }

    impl<T: Ord> Default for MinHeap<T> {
    fn default() -> Self {
    Self::new()
    }
    }
    +
    use std::cmp::{Ord, Reverse};
    use std::collections::BinaryHeap;

    pub struct MinHeap<T> {
    heap: BinaryHeap<Reverse<T>>,
    }

    impl<T: Ord> MinHeap<T> {
    pub fn new() -> MinHeap<T> {
    MinHeap {
    heap: BinaryHeap::new(),
    }
    }

    pub fn push(&mut self, item: T) {
    self.heap.push(Reverse(item))
    }

    pub fn pop(&mut self) -> Option<T> {
    self.heap.pop().map(|Reverse(x)| x)
    }
    }

    impl<T: Ord> Default for MinHeap<T> {
    fn default() -> Self {
    Self::new()
    }
    }

    Rest is just the algorithm implementation which is not that interesting.

    Day 25: Full of Hot Air

    tl;dr

    Playing around with a numbers in a special base.

    @@ -566,7 +566,7 @@ with a rather easy solution, as the last day always seems to be.

    that sounds familiar, doesn't it? Let's introduce a structure for the SNAFU numbers and implement the traits that we need.

    Let's start with a structure:

    -
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
    struct SNAFU {
    value: i64,
    }
    +
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
    struct SNAFU {
    value: i64,
    }

    Converting from &str

    We will start by implementing the FromStr trait that will help us parse our input. This is rather simple, I can just take the from_snafu function, copy-paste it @@ -585,13 +585,13 @@ trait for the SNAFU.

    After those changes we need to adjust the code and tests.

    Parsing of the input is very easy, before we have used the lines, now we parse everything:

    -
         fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
    - file_to_lines(pathname)
    + file_to_structs(pathname)
    }
    +
         fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
    - file_to_lines(pathname)
    + file_to_structs(pathname)
    }

    Part 1 needs to be adjusted a bit too:

    -
         fn part_1(input: &Input) -> Output {
    - to_snafu(input.iter().map(|s| from_snafu(s)).sum())
    + SNAFU::from(input.iter().map(|s| s.value).sum::<i64>()).to_string()
    }
    +
         fn part_1(input: &Input) -> Output {
    - to_snafu(input.iter().map(|s| from_snafu(s)).sum())
    + SNAFU::from(input.iter().map(|s| s.value).sum::<i64>()).to_string()
    }

    You can also see that it simplifies the meaning a bit and it is more explicit than the previous versions.

    And for the tests:

    -
         #[test]
    fn test_from() {
    - for (n, s) in EXAMPLES.iter() {
    - assert_eq!(from_snafu(s), *n);
    + for (&n, s) in EXAMPLES.iter() {
    + assert_eq!(s.parse::<SNAFU>().unwrap().value, n);
    }
    }

    #[test]
    fn test_to() {
    - for (n, s) in EXAMPLES.iter() {
    - assert_eq!(to_snafu(*n), s.to_string());
    + for (&n, s) in EXAMPLES.iter() {
    + assert_eq!(SNAFU::from(n).to_string(), s.to_string());
    }
    +
         #[test]
    fn test_from() {
    - for (n, s) in EXAMPLES.iter() {
    - assert_eq!(from_snafu(s), *n);
    + for (&n, s) in EXAMPLES.iter() {
    + assert_eq!(s.parse::<SNAFU>().unwrap().value, n);
    }
    }

    #[test]
    fn test_to() {
    - for (n, s) in EXAMPLES.iter() {
    - assert_eq!(to_snafu(*n), s.to_string());
    + for (&n, s) in EXAMPLES.iter() {
    + assert_eq!(SNAFU::from(n).to_string(), s.to_string());
    }

    Summary

    Let's wrap the whole thing up! Keeping in mind both AoC and the Rust…

    Finished advent calendar :smile:

    @@ -653,7 +653,7 @@ to implement the indexing in a graph, rather than explicitly access the underlying data structure.

    Here you can see a rather short snippet from the solution that allows you to “index” the graph:

    -
    impl Index<&str> for Graph {
    type Output = Vertex;

    fn index(&self, index: &str) -> &Self::Output {
    &self.g[index]
    }
    }
    +
    impl Index<&str> for Graph {
    type Output = Vertex;

    fn index(&self, index: &str) -> &Self::Output {
    &self.g[index]
    }
    }

    Cartesian product

    During the implementation I had to utilize Floyd-Warshall algorithm for finding the shortest path between pairs of vertices and utilized the iproduct! macro @@ -667,7 +667,7 @@ also makes it harder to evaluate algorithmically, since you need to check the different ways the work can be split.

    Being affected by functional programming brain damage™️, I have chosen to do this part by function that returns an iterator over the possible ways:

    -
    fn pairings(
    valves: &BTreeSet<String>,
    ) -> impl Iterator<Item = (BTreeSet<String>, BTreeSet<String>)> + '_ {
    let mapping = valves.iter().collect_vec();

    let max_mask = 1 << (valves.len() - 1);

    (0..max_mask).map(move |mask| {
    let mut elephant = BTreeSet::new();
    let mut human = BTreeSet::new();

    for (i, &v) in mapping.iter().enumerate() {
    if (mask & (1 << i)) == 0 {
    human.insert(v.clone());
    } else {
    elephant.insert(v.clone());
    }
    }

    (human, elephant)
    })
    }
    +
    fn pairings(
    valves: &BTreeSet<String>,
    ) -> impl Iterator<Item = (BTreeSet<String>, BTreeSet<String>)> + '_ {
    let mapping = valves.iter().collect_vec();

    let max_mask = 1 << (valves.len() - 1);

    (0..max_mask).map(move |mask| {
    let mut elephant = BTreeSet::new();
    let mut human = BTreeSet::new();

    for (i, &v) in mapping.iter().enumerate() {
    if (mask & (1 << i)) == 0 {
    human.insert(v.clone());
    } else {
    elephant.insert(v.clone());
    }
    }

    (human, elephant)
    })
    }

    Day 17: Pyroclastic Flow

    tl;dr

    Simulating an autonomous Tetris where pieces get affected by a series of jets of hot gas.

    @@ -678,7 +678,7 @@ hot gas.

    iterate through the positions that can actually collide with the wall or other piece.

    To get the desired behaviour, you can just compose few smaller functions:

    -
    fn occupied(shape: &[Vec<char>]) -> impl Iterator<Item = Position> + '_ {
    shape.iter().enumerate().flat_map(|(y, row)| {
    row.iter().enumerate().filter_map(move |(x, c)| {
    if c == &'#' {
    Some(Vector2D::new(x as isize, y as isize))
    } else {
    None
    }
    })
    })
    }
    +
    fn occupied(shape: &[Vec<char>]) -> impl Iterator<Item = Position> + '_ {
    shape.iter().enumerate().flat_map(|(y, row)| {
    row.iter().enumerate().filter_map(move |(x, c)| {
    if c == &'#' {
    Some(Vector2D::new(x as isize, y as isize))
    } else {
    None
    }
    })
    })
    }

    In the end, we get relative positions which we can adjust later when given the specific positions from iterator. You can see some interesting parts in this:

      @@ -697,7 +697,7 @@ and also unwraps the values from Some(…). jets that move our pieces around. Initially I have implemented my own infinite iterator that just yields the indices. It is a very simple, yet powerful, piece of code:

      -
      struct InfiniteIndex {
      size: usize,
      i: usize,
      }

      impl InfiniteIndex {
      fn new(size: usize) -> InfiniteIndex {
      InfiniteIndex { size, i: size - 1 }
      }
      }

      impl Iterator for InfiniteIndex {
      type Item = usize;

      fn next(&mut self) -> Option<Self::Item> {
      self.i = (self.i + 1) % self.size;
      Some(self.i)
      }
      }
      +
      struct InfiniteIndex {
      size: usize,
      i: usize,
      }

      impl InfiniteIndex {
      fn new(size: usize) -> InfiniteIndex {
      InfiniteIndex { size, i: size - 1 }
      }
      }

      impl Iterator for InfiniteIndex {
      type Item = usize;

      fn next(&mut self) -> Option<Self::Item> {
      self.i = (self.i + 1) % self.size;
      Some(self.i)
      }
      }

      However when I'm looking at the code now, it doesn't really make much sense… Guess what, we can use a built-in function that is implemented on iterators for that! The function is called .cycle()

      @@ -743,13 +743,13 @@ the Rc<RefCell<T>>. In the end I failed on wrong an a rather interesting issue with .borrow_mut() method being used on Rc<RefCell<T>>.

      .borrow_mut()

      Consider the following snippet of the code (taken from the documentation):

      -
      use std::cell::{RefCell, RefMut};
      use std::collections::HashMap;
      use std::rc::Rc;
      // use std::borrow::BorrowMut;

      fn main() {
      let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
      // Create a new block to limit the scope of the dynamic borrow
      {
      let mut map: RefMut<_> = shared_map.borrow_mut();
      map.insert("africa", 92388);
      map.insert("kyoto", 11837);
      map.insert("piccadilly", 11826);
      map.insert("marbles", 38);
      }

      // Note that if we had not let the previous borrow of the cache fall out
      // of scope then the subsequent borrow would cause a dynamic thread panic.
      // This is the major hazard of using `RefCell`.
      let total: i32 = shared_map.borrow().values().sum();
      println!("{total}");
      }
      +
      use std::cell::{RefCell, RefMut};
      use std::collections::HashMap;
      use std::rc::Rc;
      // use std::borrow::BorrowMut;

      fn main() {
      let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
      // Create a new block to limit the scope of the dynamic borrow
      {
      let mut map: RefMut<_> = shared_map.borrow_mut();
      map.insert("africa", 92388);
      map.insert("kyoto", 11837);
      map.insert("piccadilly", 11826);
      map.insert("marbles", 38);
      }

      // Note that if we had not let the previous borrow of the cache fall out
      // of scope then the subsequent borrow would cause a dynamic thread panic.
      // This is the major hazard of using `RefCell`.
      let total: i32 = shared_map.borrow().values().sum();
      println!("{total}");
      }

      We allocate a hash map on the heap and then in the inner block, we borrow it as a mutable reference, so that we can use it.

      note

      It is a very primitive example for Rc<RefCell<T>> and mutable borrow.

      If you uncomment the 4th line with use std::borrow::BorrowMut;, you cannot compile the code anymore, because of

      -
         Compiling playground v0.0.1 (/playground)
      error[E0308]: mismatched types
      --> src/main.rs:10:34
      |
      10 | let mut map: RefMut<_> = shared_map.borrow_mut();
      | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference
      | |
      | expected due to this
      |
      = note: expected struct `RefMut<'_, _>`
      found mutable reference `&mut Rc<RefCell<HashMap<_, _>>>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:11:13
      |
      11 | map.insert("africa", 92388);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:12:13
      |
      12 | map.insert("kyoto", 11837);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:13:13
      |
      13 | map.insert("piccadilly", 11826);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:14:13
      |
      14 | map.insert("marbles", 38);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      Some errors have detailed explanations: E0308, E0599.
      For more information about an error, try `rustc --explain E0308`.
      error: could not compile `playground` due to 5 previous errors
      +
         Compiling playground v0.0.1 (/playground)
      error[E0308]: mismatched types
      --> src/main.rs:10:34
      |
      10 | let mut map: RefMut<_> = shared_map.borrow_mut();
      | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference
      | |
      | expected due to this
      |
      = note: expected struct `RefMut<'_, _>`
      found mutable reference `&mut Rc<RefCell<HashMap<_, _>>>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:11:13
      |
      11 | map.insert("africa", 92388);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:12:13
      |
      12 | map.insert("kyoto", 11837);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:13:13
      |
      13 | map.insert("piccadilly", 11826);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      error[E0599]: no method named `insert` found for struct `RefMut<'_, _>` in the current scope
      --> src/main.rs:14:13
      |
      14 | map.insert("marbles", 38);
      | ^^^^^^ method not found in `RefMut<'_, _>`

      Some errors have detailed explanations: E0308, E0599.
      For more information about an error, try `rustc --explain E0308`.
      error: could not compile `playground` due to 5 previous errors

      It might seem a bit ridiculous. However, I got to a point where the compiler suggested use std::borrow::BorrowMut; and it resulted in breaking parts of the code that worked previously. I think it may be a good idea to go over what is @@ -776,14 +776,14 @@ method. OK, but how can we call it on the Rc<T>? Easily! I have not been able to find a lot on this trait. My guess is that it provides a method instead of a syntactic sugar (&mut x) for the mutable borrow. And also it provides default implementations for the types:

      -
      impl BorrowMut<str> for String

      impl<T> BorrowMut<T> for &mut T
      where
      T: ?Sized,

      impl<T> BorrowMut<T> for T
      where
      T: ?Sized,

      impl<T, A> BorrowMut<[T]> for Vec<T, A>
      where
      A: Allocator,

      impl<T, A> BorrowMut<T> for Box<T, A>
      where
      A: Allocator,
      T: ?Sized,

      impl<T, const N: usize> BorrowMut<[T]> for [T; N]
      +
      impl BorrowMut<str> for String

      impl<T> BorrowMut<T> for &mut T
      where
      T: ?Sized,

      impl<T> BorrowMut<T> for T
      where
      T: ?Sized,

      impl<T, A> BorrowMut<[T]> for Vec<T, A>
      where
      A: Allocator,

      impl<T, A> BorrowMut<T> for Box<T, A>
      where
      A: Allocator,
      T: ?Sized,

      impl<T, const N: usize> BorrowMut<[T]> for [T; N]
      Conflict

      Now the question is why did it break the code… My first take was that the type Rc<RefCell<T>> has some specialized implementation of the .borrow_mut() and the use overrides it with the default, which is true in a sense. However there is no specialized implementation. Let's have a look at the trait and the type signature on the RefCell<T>:

      -
      // trait
      pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
      where
      Borrowed: ?Sized,
      {
      fn borrow_mut(&mut self) -> &mut Borrowed;
      }

      // ‹RefCell<T>.borrow_mut()› type signature
      pub fn borrow_mut(&self) -> RefMut<'_, T>
      +
      // trait
      pub trait BorrowMut<Borrowed>: Borrow<Borrowed>
      where
      Borrowed: ?Sized,
      {
      fn borrow_mut(&mut self) -> &mut Borrowed;
      }

      // ‹RefCell<T>.borrow_mut()› type signature
      pub fn borrow_mut(&self) -> RefMut<'_, T>

      I think that we can definitely agree on the fact that RefMut<'_, T> is not the RefCell<T>.

      In my opinion, RefCell<T> implements a separate .borrow_mut() rather @@ -810,7 +810,7 @@ as:

      that you can use the macro machinery to save yourself some typing. If you have enumeration of which the default value doesn't bear any parameter, you can just do2:

      -
      #[derive(Default)]
      enum Color {
      #[default]
      White,
      Gray,
      Black,
      }
      +
      #[derive(Default)]
      enum Color {
      #[default]
      White,
      Gray,
      Black,
      }

      Abusing negation

      If you want to use a unary minus operator on your own type, you can implement a Neg trait3. I was dealing with a binary tree and needed a way how to look @@ -857,26 +857,26 @@ order and return the resulting matrix.

      Image describing the problem

      Skeleton and initial adjustments

      We are given the following skeleton for the C++ and the given challenge:

      -
      class Solution {
      public:
      vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {

      }
      };
      +
      class Solution {
      public:
      vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {

      }
      };

      The task is to sort the passed matrix diagonally and then return it. First of all, I don't like to solve this in a web browser, so we'll need to adjust it accordingly for running it locally. We'll start by including the vector header and using fully-qualified namespaces1 and also adding few tests:

      -
      #include <cassert>
      #include <vector>

      using matrix = std::vector<std::vector<int>>;

      class Solution {
      public:
      matrix diagonalSort(matrix& mat)
      {
      }
      };

      static void test_case_1()
      {
      // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
      // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
      std::vector { 2, 2, 1, 2 },
      std::vector { 1, 1, 1, 2 } })
      == std::vector { std::vector { 1, 1, 1, 1 },
      std::vector { 1, 2, 2, 2 },
      std::vector { 1, 2, 3, 3 } }));
      }

      static void test_case_2()
      {
      // Input: mat =
      // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
      // Output:
      // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
      std::vector { 23, 55, 17, 45, 15, 52 },
      std::vector { 75, 31, 36, 44, 58, 8 },
      std::vector { 22, 27, 33, 25, 68, 4 },
      std::vector { 84, 28, 14, 11, 5, 50 } })
      == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
      std::vector { 11, 11, 25, 45, 8, 69 },
      std::vector { 14, 23, 25, 44, 58, 15 },
      std::vector { 22, 27, 31, 36, 50, 66 },
      std::vector { 84, 28, 75, 33, 55, 68 } }));
      }

      int main()
      {
      test_case_1();
      test_case_2();

      return 0;
      }
      +
      #include <cassert>
      #include <vector>

      using matrix = std::vector<std::vector<int>>;

      class Solution {
      public:
      matrix diagonalSort(matrix& mat)
      {
      }
      };

      static void test_case_1()
      {
      // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
      // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
      std::vector { 2, 2, 1, 2 },
      std::vector { 1, 1, 1, 2 } })
      == std::vector { std::vector { 1, 1, 1, 1 },
      std::vector { 1, 2, 2, 2 },
      std::vector { 1, 2, 3, 3 } }));
      }

      static void test_case_2()
      {
      // Input: mat =
      // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
      // Output:
      // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]

      Solution s;
      assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
      std::vector { 23, 55, 17, 45, 15, 52 },
      std::vector { 75, 31, 36, 44, 58, 8 },
      std::vector { 22, 27, 33, 25, 68, 4 },
      std::vector { 84, 28, 14, 11, 5, 50 } })
      == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
      std::vector { 11, 11, 25, 45, 8, 69 },
      std::vector { 14, 23, 25, 44, 58, 15 },
      std::vector { 22, 27, 31, 36, 50, 66 },
      std::vector { 84, 28, 75, 33, 55, 68 } }));
      }

      int main()
      {
      test_case_1();
      test_case_2();

      return 0;
      }

      We need to return the matrix, but we're given a reference to the input matrix. We can easily abuse the C++ here and just switch the reference to value, this way the matrix will be copied when passed to the function, we can sort the copy and just return it back. And we also get yelled by the compiler for the fact that the method doesn't return anything yet, so to make it “shut up” we will just return the input for now:

      -
      -    matrix diagonalSort(matrix& mat)
      + matrix diagonalSort(matrix mat)
      {
      + return mat;
      }
      +
      -    matrix diagonalSort(matrix& mat)
      + matrix diagonalSort(matrix mat)
      {
      + return mat;
      }

      Now, we get the copy and we're good to go.

      Naïve solution

      As you may know, C++ offers a plethora of functions that can be used to your advantage, given that you know how to “bend” the data structures accordingly.

      What does that mean for us? Well, we have an std::sort, we can use it, right? Let's have a look at it:

      -
      template< class RandomIt >
      void sort( RandomIt first, RandomIt last );
      +
      template< class RandomIt >
      void sort( RandomIt first, RandomIt last );

      This overload is more than we need. What does it do? It just sorts the elements in the range [first, last) using operator< on them. We can't sort the whole matrix using this, but… we can sort just »one« diagonal without doing much work @@ -894,10 +894,10 @@ up, i.e. “compiler-assisted development3. And that way we get

      -
      matrix diagonalSort(matrix mat)
      {
      // we iterate over the diagonals
      for (auto d : diagonals(mat)) {
      // and we sort each diagonal
      std::sort(d.begin(), d.end());
      }

      // we take the matrix by copy, so we can sort in-situ and return the copy
      // that we sorted
      return mat;
      }
      +
      matrix diagonalSort(matrix mat)
      {
      // we iterate over the diagonals
      for (auto d : diagonals(mat)) {
      // and we sort each diagonal
      std::sort(d.begin(), d.end());
      }

      // we take the matrix by copy, so we can sort in-situ and return the copy
      // that we sorted
      return mat;
      }

      This solution looks very simple, doesn't it? Well, cause it is. Let's try compiling it:

      -
      matrix-sort.cpp:11:23: error: use of undeclared identifier 'diagonals' [clang-diagnostic-error]
      for (auto d : diagonals(mat)) {
      ^
      Found compiler error(s).
      make: *** [makefile:14: tidy] Error 1
      +
      matrix-sort.cpp:11:23: error: use of undeclared identifier 'diagonals' [clang-diagnostic-error]
      for (auto d : diagonals(mat)) {
      ^
      Found compiler error(s).
      make: *** [makefile:14: tidy] Error 1

      OK, seems about right. We haven't implemented the diagonals yet. And based on what we've written so far, we need a function or a class diagonals that will give us the diagonals we need.

      @@ -912,7 +912,7 @@ do such functionality for a matrix of any type, not just the int fr
    • get the beginning
    • get the end (the “sentinel”)
    -
    template <typename T>
    class diagonals {
    using matrix_t = std::vector<std::vector<T>>;

    matrix_t& _matrix;

    public:
    diagonals(matrix_t& m)
    : _matrix(m)
    {
    }
    diagonals_iter begin()
    {
    /* TODO */
    }
    diagonals_iter end()
    {
    /* TODO */
    }
    };
    +
    template <typename T>
    class diagonals {
    using matrix_t = std::vector<std::vector<T>>;

    matrix_t& _matrix;

    public:
    diagonals(matrix_t& m)
    : _matrix(m)
    {
    }
    diagonals_iter begin()
    {
    /* TODO */
    }
    diagonals_iter end()
    {
    /* TODO */
    }
    };

    Now we have a diagonals that we can use to go through the diagonals. We haven't implemented the core of it yet. Let's go through what we have for now.

    We have a templated class with templated T that is used as a placeholder for any @@ -931,7 +931,7 @@ in the first row, followed by the rest of the diagonals in the first column.

    need to know which diagonal is next. For that purpose we will pass the indices of the first cell on the diagonal. That way we can always tell how to move forward.

    We will start by updating the begin and end to reflect our choice accordingly.

    -
    diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
    diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }
    +
    diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
    diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }

    For the begin we return the first diagonal that starts at (0, 0). And because we have decided to do the diagonals in the first column at the end, the first diagonal that is not a valid one is the one at (0, height). Apart from the @@ -945,7 +945,7 @@ don't care about the fact they don't need to be sorted.

    We can start with a simple skeleton based on the information that we pass from the diagonals. Also to utilize the matrix_t and also contain implementation details hidden away, we will put this code into the diagonals class.

    -
    class diagonals_iter {
    matrix_t& m;
    std::size_t x;
    std::size_t y;

    public:
    diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
    : m(matrix)
    , x(x)
    , y(y)
    {
    }
    };
    +
    class diagonals_iter {
    matrix_t& m;
    std::size_t x;
    std::size_t y;

    public:
    diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
    : m(matrix)
    , x(x)
    , y(y)
    {
    }
    };

    In this case we will be implementing a “simple” forward iterator, so we don't need to implement a lot. Notably it will be:

      @@ -955,12 +955,12 @@ iterate over)
    • dereference operator (we need to be able to retrieve the objects we iterate over)
    -
    class diagonals_iter {
    matrix_t& m;
    std::size_t x;
    std::size_t y;

    public:
    diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
    : m(matrix)
    , x(x)
    , y(y)
    {
    }

    bool operator!=(const diagonals_iter& rhs) const
    {
    // iterators are not equal if they reference different matrices, or
    // their positions differ
    return m != rhs.m || x != rhs.x || y != rhs.y;
    }

    diagonals_iter& operator++()
    {
    if (y != 0) {
    // iterating through diagonals down the first column
    y++;
    return *this;
    }

    // iterating the diagonals along the first row
    x++;
    if (x == m.front().size()) {
    // switching to diagonals in the first column
    x = 0;
    y++;
    }

    return *this;
    }

    diagonal<T> operator*() const { return diagonal { m, x, y }; }
    };
    +
    class diagonals_iter {
    matrix_t& m;
    std::size_t x;
    std::size_t y;

    public:
    diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
    : m(matrix)
    , x(x)
    , y(y)
    {
    }

    bool operator!=(const diagonals_iter& rhs) const
    {
    // iterators are not equal if they reference different matrices, or
    // their positions differ
    return m != rhs.m || x != rhs.x || y != rhs.y;
    }

    diagonals_iter& operator++()
    {
    if (y != 0) {
    // iterating through diagonals down the first column
    y++;
    return *this;
    }

    // iterating the diagonals along the first row
    x++;
    if (x == m.front().size()) {
    // switching to diagonals in the first column
    x = 0;
    y++;
    }

    return *this;
    }

    diagonal<T> operator*() const { return diagonal { m, x, y }; }
    };

    Let's go one-by-one. Inequality operator is rather simple, just compare iterator's attributes field-by-field. If you think about it, checking inequality of two 2D vectors may be a bit inefficient, therefore, we can swap around and check it as a last thing.

    -
    -        return m != rhs.m || x != rhs.x || y != rhs.y;
    + return x != rhs.x || y != rhs.y || m != rhs.m;
    +
    -        return m != rhs.m || x != rhs.x || y != rhs.y;
    + return x != rhs.x || y != rhs.y || m != rhs.m;

    Preincrementation is where the magic happens. If you have a better look, you can see two branches of this operation:

      @@ -980,7 +980,7 @@ something else. In our case it will be a class called diagonal.

      a diagonal is the matrix itself and the “start” of the diagonal (row and column). And we also know that the diagonal must provide some iterators for the std::sort function. We can start with the following skeleton:

      -
      template <typename T>
      class diagonal {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& matrix;
      std::size_t x;
      std::size_t y;

      public:
      diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
      : matrix(matrix)
      , x(x)
      , y(y)
      {
      }

      diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }

      diagonal_iter end() const
      {
      auto max_x = matrix[y].size();
      auto max_y = matrix.size();

      // we need to find the distance in which we get out of bounds (either in
      // column or row)
      auto steps = std::min(max_x - x, max_y - y);

      return diagonal_iter { matrix, x + steps, y + steps };
      }
      };
      +
      template <typename T>
      class diagonal {
      using matrix_t = std::vector<std::vector<T>>;

      matrix_t& matrix;
      std::size_t x;
      std::size_t y;

      public:
      diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
      : matrix(matrix)
      , x(x)
      , y(y)
      {
      }

      diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }

      diagonal_iter end() const
      {
      auto max_x = matrix[y].size();
      auto max_y = matrix.size();

      // we need to find the distance in which we get out of bounds (either in
      // column or row)
      auto steps = std::min(max_x - x, max_y - y);

      return diagonal_iter { matrix, x + steps, y + steps };
      }
      };

      Initialization is rather simple, we just “keep” the stuff we get, begin is the simplest, we just delegate.

      In case of the end, it gets more complicated. We need to know where is the “end” @@ -1007,7 +1007,7 @@ be used in std::sort. We need the usual operations like:

      We will also add all the types that our iterator uses with the category of the iterator, i.e. what interface it supports:

      -
      class diagonal_iter {
      // we need to keep reference to the matrix itself
      matrix_t& m;

      // we need to be able to tell our current position
      std::size_t x;
      std::size_t y;

      public:
      using difference_type = std::ptrdiff_t;
      using value_type = T;
      using pointer = T*;
      using reference = T&;
      using iterator_category = std::random_access_iterator_tag;

      diagonal_iter(matrix_t& matrix,
      std::size_t x,
      std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator==(const diagonal_iter& rhs) const
      {
      return x == rhs.x && y == rhs.y && m == rhs.m;
      }

      diagonal_iter& operator++()
      {
      // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
      // the same time
      x++;
      y++;
      return *this;
      }

      reference operator*() const { return m[y][x]; }
      };
      +
      class diagonal_iter {
      // we need to keep reference to the matrix itself
      matrix_t& m;

      // we need to be able to tell our current position
      std::size_t x;
      std::size_t y;

      public:
      using difference_type = std::ptrdiff_t;
      using value_type = T;
      using pointer = T*;
      using reference = T&;
      using iterator_category = std::random_access_iterator_tag;

      diagonal_iter(matrix_t& matrix,
      std::size_t x,
      std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator==(const diagonal_iter& rhs) const
      {
      return x == rhs.x && y == rhs.y && m == rhs.m;
      }

      diagonal_iter& operator++()
      {
      // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
      // the same time
      x++;
      y++;
      return *this;
      }

      reference operator*() const { return m[y][x]; }
      };

      This is pretty similar to the previous iterator, but now we need to implement the remaining requirements of the random access iterator. Let's see what those are:

        @@ -1018,16 +1018,16 @@ remaining requirements of the random access iterator. Let's see what th
      • define an ordering on the iterators

      Let's fill them in:

      -
      class diagonal_iter {
      // we need to keep reference to the matrix itself
      matrix_t& m;

      // we need to be able to tell our current position
      std::size_t x;
      std::size_t y;

      public:
      using difference_type = std::ptrdiff_t;
      using value_type = T;
      using pointer = T*;
      using reference = T&;
      using iterator_category = std::random_access_iterator_tag;

      diagonal_iter(matrix_t& matrix,
      std::size_t x,
      std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator==(const diagonal_iter& rhs) const
      {
      return x == rhs.x && y == rhs.y && m == rhs.m;
      }

      diagonal_iter& operator++()
      {
      // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
      // the same time
      x++;
      y++;
      return *this;
      }

      reference operator*() const { return m[y][x]; }

      // exactly opposite to the incrementation
      diagonal_iter operator--()
      {
      x--;
      y--;
      return *this;
      }

      // moving ‹n› steps back is same as calling decrementation ‹n›-times, so we
      // can just return a new iterator and subtract ‹n› from both coordinates in
      // the matrix
      diagonal_iter operator-(difference_type n) const
      {
      return diagonal_iter { m, x - n, y - n };
      }

      // here we assume that we are given two iterators on the same diagonal
      difference_type operator-(const diagonal_iter& rhs) const
      {
      assert(m == rhs.m);
      return x - rhs.x;
      }

      // counterpart of moving ‹n› steps backwards
      diagonal_iter operator+(difference_type n) const
      {
      return diagonal_iter { m, x + n, y + n };
      }

      // we compare the coordinates, and also assume that those 2 iterators are
      // lying on the same diagonal
      bool operator<(const diagonal_iter& rhs) const
      {
      assert(m == rhs.m);
      return x < rhs.x && y < rhs.y;
      }
      };
      +
      class diagonal_iter {
      // we need to keep reference to the matrix itself
      matrix_t& m;

      // we need to be able to tell our current position
      std::size_t x;
      std::size_t y;

      public:
      using difference_type = std::ptrdiff_t;
      using value_type = T;
      using pointer = T*;
      using reference = T&;
      using iterator_category = std::random_access_iterator_tag;

      diagonal_iter(matrix_t& matrix,
      std::size_t x,
      std::size_t y)
      : m(matrix)
      , x(x)
      , y(y)
      {
      }

      bool operator==(const diagonal_iter& rhs) const
      {
      return x == rhs.x && y == rhs.y && m == rhs.m;
      }

      diagonal_iter& operator++()
      {
      // we are moving along the diagonal, so we increment both ‹x› and ‹y› at
      // the same time
      x++;
      y++;
      return *this;
      }

      reference operator*() const { return m[y][x]; }

      // exactly opposite to the incrementation
      diagonal_iter operator--()
      {
      x--;
      y--;
      return *this;
      }

      // moving ‹n› steps back is same as calling decrementation ‹n›-times, so we
      // can just return a new iterator and subtract ‹n› from both coordinates in
      // the matrix
      diagonal_iter operator-(difference_type n) const
      {
      return diagonal_iter { m, x - n, y - n };
      }

      // here we assume that we are given two iterators on the same diagonal
      difference_type operator-(const diagonal_iter& rhs) const
      {
      assert(m == rhs.m);
      return x - rhs.x;
      }

      // counterpart of moving ‹n› steps backwards
      diagonal_iter operator+(difference_type n) const
      {
      return diagonal_iter { m, x + n, y + n };
      }

      // we compare the coordinates, and also assume that those 2 iterators are
      // lying on the same diagonal
      bool operator<(const diagonal_iter& rhs) const
      {
      assert(m == rhs.m);
      return x < rhs.x && y < rhs.y;
      }
      };

      At this point we could probably try and compile it, right? If we do so, we will get yelled at by a compiler for the following reasons:

      -
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
      __last = __next;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization 'std::__unguarded_linear_insert<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>' requested here
      std::__unguarded_linear_insert(__i,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization 'std::__insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__final_insertion_sort(__first, __last, __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to '__unguarded_linear_insert' [clang-diagnostic-error]
      std::__unguarded_linear_insert(__i,
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization 'std::__unguarded_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__final_insertion_sort(__first, __last, __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal<int>::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]
      __unguarded_linear_insert(_RandomAccessIterator __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
      __last = __cut;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization 'std::__introsort_loop<diagonal<int>::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__introsort_loop(__first, __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      +
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
      __last = __next;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization 'std::__unguarded_linear_insert<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>' requested here
      std::__unguarded_linear_insert(__i,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization 'std::__insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__final_insertion_sort(__first, __last, __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to '__unguarded_linear_insert' [clang-diagnostic-error]
      std::__unguarded_linear_insert(__i,
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization 'std::__unguarded_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization 'std::__final_insertion_sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__final_insertion_sort(__first, __last, __comp);
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal<int>::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]
      __unguarded_linear_insert(_RandomAccessIterator __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]
      __last = __cut;
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization 'std::__introsort_loop<diagonal<int>::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__introsort_loop(__first, __last,
      ^
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization 'std::__sort<diagonal<int>::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>' requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      ^
      matrix-sort.cpp:161:18: note: in instantiation of function template specialization 'std::sort<diagonal<int>::diagonal_iter>' requested here
      std::sort(d.begin(), d.end());
      ^
      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^

      That's a lot of noise, isn't it? Let's focus on the important parts:

      -
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]

      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^
      +
      /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type 'diagonal<int>::diagonal_iter' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]

      matrix-sort.cpp:17:19: note: copy assignment operator of 'diagonal_iter' is implicitly deleted because field 'm' is of reference type 'diagonal<int>::matrix_t &' (aka 'vector<std::vector<int>> &')
      matrix_t& m;
      ^

      Ah! We have a reference in our iterator, and this prevents us from having a copy assignment operator (that is used “somewhere” in the sorting algorithm). Well… Let's just wrap it!

      -
      # we need to keep a different type than reference
      - matrix_t& m;
      + std::reference_wrapper<matrix_t> m;

      # in comparison we need to get the reference out of the wrapper first
      - return x == rhs.x && y == rhs.y && m == rhs.m;
      + return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();

      # same when we return a reference to the “cell” in the matrix
      - reference operator*() const { return m[y][x]; }
      + reference operator*() const { return m.get()[y][x]; }

      # and finally in the assertions that we set for the “distance” and “less than”
      - assert(m == rhs.m);
      + assert(m.get() == rhs.m.get());
      +
      # we need to keep a different type than reference
      - matrix_t& m;
      + std::reference_wrapper<matrix_t> m;

      # in comparison we need to get the reference out of the wrapper first
      - return x == rhs.x && y == rhs.y && m == rhs.m;
      + return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();

      # same when we return a reference to the “cell” in the matrix
      - reference operator*() const { return m[y][x]; }
      + reference operator*() const { return m.get()[y][x]; }

      # and finally in the assertions that we set for the “distance” and “less than”
      - assert(m == rhs.m);
      + assert(m.get() == rhs.m.get());

      We're done now! We have written an iterator over diagonals for a 2D vector. You can have a look at the final result here.

      Footnotes

        @@ -1077,7 +1077,7 @@ own “box of hell”.

    Swapping indices

    Relatively simple implementation, just take the values, swap them and return new vector.

    -
    impl<T: Copy> Vector2D<T> {
    pub fn swap(&self) -> Self {
    Self {
    x: self.y,
    y: self.x,
    }
    }
    }
    +
    impl<T: Copy> Vector2D<T> {
    pub fn swap(&self) -> Self {
    Self {
    x: self.y,
    y: self.x,
    }
    }
    }

    Pretty straight-forward implementation, but let's talk about the T: Copy. We need to use it, since we are returning a new vector, with swapped values. If we had values that cannot be copied, the only thing we could do, would be a @@ -1086,7 +1086,7 @@ later on). This is pretty similar with the operations on sets from the first wee

    Indexing Vec

    I will start with the indexing, cause bound-checking is a bit more… complicated than I would like to.

    -
    pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }
    +
    pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }

    Let's talk about this mess… Body of the function is probably the most easy part and should not be hard to understand, we just take the x and y and convert them both to usize type that can be used later on for indexing.

    @@ -1125,20 +1125,20 @@ taken by a reference, i.e. returned reference must live at least as long as the

    First issue that our implementation has is the fact that we cannot get a mutable reference out of that function. This could be easily resolved by introducing new function, e.g. index_mut. Which I have actually done while writing this part:

    -
    pub fn index_mut<'a, T, U>(v: &'a mut [Vec<U>], idx: &Vector2D<T>) -> &'a mut U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &mut v[y][x]
    }
    +
    pub fn index_mut<'a, T, U>(v: &'a mut [Vec<U>], idx: &Vector2D<T>) -> &'a mut U
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &mut v[y][x]
    }
    «↯» Why can't we use one function?

    When we consider a Vec<T>, we don't need to consider containers as T, Rust implements indexing as traits Index<T> and IndexMut<T> that do the dirty work behind syntactic sugar of container[idx].

    However, implementing of traits is not allowed for external types, i.e. types that you haven't defined yourself. This means that you can implement indexing over containers that you have implemented yourself, but you cannot use your own types for indexing “built-in” types.

    Another part of this rabbit hole is trait SliceIndex<T> that is of a relevance -because of

    impl<T, I> Index<I> for [T]
    where
    I: SliceIndex<[T]>

    impl<T, I, A> Index<I> for Vec<T, A>
    where
    I: SliceIndex<[T]>,
    A: Allocator

    impl<T, I, const N: usize> Index<I> for [T; N]
    where
    [T]: Index<I>

    In other words, if your type implements SliceIndex<T> trait, it can be used +because of

    impl<T, I> Index<I> for [T]
    where
    I: SliceIndex<[T]>

    impl<T, I, A> Index<I> for Vec<T, A>
    where
    I: SliceIndex<[T]>,
    A: Allocator

    impl<T, I, const N: usize> Index<I> for [T; N]
    where
    [T]: Index<I>

    In other words, if your type implements SliceIndex<T> trait, it can be used for indexing. As of now, this trait has all of its required methods experimental and is marked as unsafe.

    Another problem is a requirement for indexing either [Vec<T>] or Vec<Vec<T>>. This requirement could be countered by removing inner type Vec<T> and constraining it by a trait Index (or IndexMut respectively) in a following way

    -
    pub fn index<'a, C, T>(v: &'a [C], idx: &Vector2D<T>) -> &'a C::Output
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    C: Index<usize>
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }
    +
    pub fn index<'a, C, T>(v: &'a [C], idx: &Vector2D<T>) -> &'a C::Output
    where
    usize: TryFrom<T>,
    <usize as TryFrom<T>>::Error: Debug,
    T: Copy,
    C: Index<usize>
    {
    let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
    &v[y][x]
    }

    Given this, we can also give a more meaningful typename for indexing type, such as I.

    Checking bounds

    @@ -1149,12 +1149,12 @@ up with negative values which, unlike in C++, causes an error (instead of underf that you can use to your advantage; you can easily guess how).

    So how can we approach this then? Well… we will convert the bounds instead of the indices and that lead us to:

    -
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    usize: TryInto<T>,
    <usize as TryInto<T>>::Error: Debug,
    T: PartialOrd + Copy,
    {
    idx.y >= 0.try_into().unwrap()
    && idx.y < v.len().try_into().unwrap()
    && idx.x >= 0.try_into().unwrap()
    && idx.x
    < v[TryInto::<usize>::try_into(idx.y).unwrap()]
    .len()
    .try_into()
    .unwrap()
    }
    +
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    usize: TryInto<T>,
    <usize as TryInto<T>>::Error: Debug,
    T: PartialOrd + Copy,
    {
    idx.y >= 0.try_into().unwrap()
    && idx.y < v.len().try_into().unwrap()
    && idx.x >= 0.try_into().unwrap()
    && idx.x
    < v[TryInto::<usize>::try_into(idx.y).unwrap()]
    .len()
    .try_into()
    .unwrap()
    }

    You can tell that it's definitely a shitty code. Let's improve it now! We will get back to the original idea, but do it better. We know that we cannot convert negative values into usize, but we also know that conversion like that returns a Result<T, E> which we can use to our advantage.

    -
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    T: Copy,
    usize: TryFrom<T>,
    {
    usize::try_from(idx.y)
    .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))
    .unwrap_or(false)
    }
    +
    pub fn in_range<T, U>(v: &[Vec<U>], idx: &Vector2D<T>) -> bool
    where
    T: Copy,
    usize: TryFrom<T>,
    {
    usize::try_from(idx.y)
    .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))
    .unwrap_or(false)
    }

    Result<T, E> is a type similar to Either in Haskell and it allows us to chain multiple operations on correct results or propagate the original error without doing anything. Let's dissect it one-by-one.

    @@ -1163,7 +1163,7 @@ types and either successfully convert them or fail (with a reasonable error). Th method returns Result<T, E>.

    We call and_then on that result, let's have a look at the type signature of and_then, IMO it explains more than enough:

    -
    pub fn and_then<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> Result<U, E>
    +
    pub fn and_then<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> Result<U, E>

    OK… So it takes the result and a function and returns another result with different value and different error. However we can see that the function, which represents an operation on a result, takes just the value, i.e. it doesn't care @@ -1173,7 +1173,7 @@ about any previous error. To make it short:

    We parsed a y index and now we try to convert the x index with try_from again, but on that result we use map rather than and_then, why would that be?

    -
    pub fn map<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> U
    +
    pub fn map<U, F>(self, op: F) -> Result<U, E>
    where
    F: FnOnce(T) -> U

    Huh… map performs an operation that cannot fail. And finally we use unwrap_or which takes the value from result, or in case of an error returns the default that we define.

    @@ -1202,13 +1202,13 @@ preparations for the AoC. Let's sum up our requirements:

    cannot do anything about it. However running and testing can be simplified!

    Let's introduce and export a new module solution that will take care of all of this. We will start by introducing a trait for each day.

    -
    pub trait Solution<Input, Output: Display> {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input;

    fn part_1(input: &Input) -> Output;
    fn part_2(input: &Input) -> Output;
    }
    +
    pub trait Solution<Input, Output: Display> {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input;

    fn part_1(input: &Input) -> Output;
    fn part_2(input: &Input) -> Output;
    }

    This does a lot of work for us already, we have defined a trait and for each day we will create a structure representing a specific day. That structure will also implement the Solution trait.

    Now we need to get rid of the boilerplate, we can't get rid of the main function, but we can at least move out the functionality.

    -
    fn run(type_of_input: &str) -> Result<()>
    where
    Self: Sized,
    {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = Self::parse_input(format!("{}s/{}.txt", type_of_input, Self::day()));

    info!("Part 1: {}", Self::part_1(&input));
    info!("Part 2: {}", Self::part_2(&input));

    Ok(())
    }

    fn main() -> Result<()>
    where
    Self: Sized,
    {
    Self::run("input")
    }
    +
    fn run(type_of_input: &str) -> Result<()>
    where
    Self: Sized,
    {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = Self::parse_input(format!("{}s/{}.txt", type_of_input, Self::day()));

    info!("Part 1: {}", Self::part_1(&input));
    info!("Part 2: {}", Self::part_2(&input));

    Ok(())
    }

    fn main() -> Result<()>
    where
    Self: Sized,
    {
    Self::run("input")
    }

    This is all part of the Solution trait, which can implement methods while being dependent on what is provided by the implementing types. In this case, we just need to bound the Output type to implement Display that is necessary for the @@ -1217,14 +1217,14 @@ need to bound the Output type to implement Display tha day() method that you can see being used when constructing path to the input file. That method will generate a name of the file, e.g. day01 and we know that we can somehow deduce it from the structure name, given we name it reasonably.

    -
    fn day() -> String {
    let mut day = String::from(type_name::<Self>().split("::").next().unwrap());
    day.make_ascii_lowercase();

    day.to_string()
    }
    +
    fn day() -> String {
    let mut day = String::from(type_name::<Self>().split("::").next().unwrap());
    day.make_ascii_lowercase();

    day.to_string()
    }
    type_name

    This feature is still experimental and considered to be internal, it is not advised to use it any production code.

    And now we can get to the nastiest stuff 😩 We will generate the tests!

    We want to be able to generate tests for sample input in a following way:

    -
    test_sample!(day_01, Day01, 42, 69);
    +
    test_sample!(day_01, Day01, 42, 69);

    There's not much we can do, so we will write a macro to generate the tests for us.

    -
    #[macro_export]
    macro_rules! test_sample {
    ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {
    #[cfg(test)]
    mod $mod_name {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_1(&sample), $part_1);
    }

    #[test]
    fn test_part_2() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_2(&sample), $part_2);
    }
    }
    };
    }
    +
    #[macro_export]
    macro_rules! test_sample {
    ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {
    #[cfg(test)]
    mod $mod_name {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_1(&sample), $part_1);
    }

    #[test]
    fn test_part_2() {
    let sample =
    $day_struct::parse_input(&format!("samples/{}.txt", $day_struct::day()));
    assert_eq!($day_struct::part_2(&sample), $part_2);
    }
    }
    };
    }

    We have used it in a similar way as macros in C/C++, one of the things that we can use to our advantage is defining “type” of the parameters for the macro. All parameters have their name prefixed with $ sign and you can define various “forms” @@ -1240,7 +1240,7 @@ which literally means an expression.

    Apart from that we need to use #[macro_export] to mark the macro as exported for usage outside of the module. Now our skeleton looks like:

    -
    use aoc_2022::*;

    type Input = String;
    type Output = String;

    struct DayXX;
    impl Solution<Input, Output> for DayXX {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
    file_to_string(pathname)
    }

    fn part_1(input: &Input) -> Output {
    todo!()
    }

    fn part_2(input: &Input) -> Output {
    todo!()
    }
    }

    fn main() -> Result<()> {
    // DayXX::run("sample")
    DayXX::main()
    }

    // test_sample!(day_XX, DayXX, , );
    +
    use aoc_2022::*;

    type Input = String;
    type Output = String;

    struct DayXX;
    impl Solution<Input, Output> for DayXX {
    fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
    file_to_string(pathname)
    }

    fn part_1(input: &Input) -> Output {
    todo!()
    }

    fn part_2(input: &Input) -> Output {
    todo!()
    }
    }

    fn main() -> Result<()> {
    // DayXX::run("sample")
    DayXX::main()
    }

    // test_sample!(day_XX, DayXX, , );

    Solution

    Not much to talk about, it is relatively easy to simulate.

    Day 10: Cathode-Ray Tube

    @@ -1250,7 +1250,7 @@ CPU's accumulator.

    And the issue is caused by different types of Output for the part 1 and part 2.

    Problem is relatively simple and consists of simulating a CPU, I have approached it in a following way:

    -
    fn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {
    instructions
    .iter()
    .fold(State::new(), |state, instruction| {
    state.execute(instruction, &mut out)
    });

    out
    }
    +
    fn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {
    instructions
    .iter()
    .fold(State::new(), |state, instruction| {
    state.execute(instruction, &mut out)
    });

    out
    }

    We just take the instructions, we have some state of the CPU and we execute the instructions one-by-one. Perfect usage of the fold (or reduce as you may know it from other languages).

    @@ -1258,11 +1258,11 @@ it from other languages).

    that problem. And the answer is very simple and functional. Rust allows you to have an enumeration that can bear some other values apart from the type itself.

    tip

    We could've seen something like this with the Result<T, E> type that can be -defined as

    enum Result<T, E> {
    Ok(T),
    Err(E)
    }
    What does that mean though?

    When we have an Ok value, it has the result itself, and when we get an Err +defined as

    enum Result<T, E> {
    Ok(T),
    Err(E)
    }
    What does that mean though?

    When we have an Ok value, it has the result itself, and when we get an Err value, it has the error. This also allows us to handle results in a rather -pretty way:

    match do_something(x) {
    Ok(y) => {
    println!("SUCCESS: {}", y);
    },
    Err(y) => {
    eprintln!("ERROR: {}", y);
    }
    }
    +pretty way:

    match do_something(x) {
    Ok(y) => {
    println!("SUCCESS: {}", y);
    },
    Err(y) => {
    eprintln!("ERROR: {}", y);
    }
    }

    My solution has a following outline:

    -
    fn execute(&self, i: &Instruction, output: &mut Output) -> State {
    // execute the instruction

    // collect results if necessary
    match output {
    Output::Part1(x) => self.execute_part_1(y, x),
    Output::Part2(x) => self.execute_part_2(y, x),
    }

    // return the obtained state
    new_state
    }
    +
    fn execute(&self, i: &Instruction, output: &mut Output) -> State {
    // execute the instruction

    // collect results if necessary
    match output {
    Output::Part1(x) => self.execute_part_1(y, x),
    Output::Part2(x) => self.execute_part_2(y, x),
    }

    // return the obtained state
    new_state
    }

    You might think that it's a perfectly reasonable thing to do. Yes, but notice that the match statement doesn't collect the changes in any way and also we pass output by &mut, so it is shared across each iteration of the fold.

    @@ -1289,7 +1289,7 @@ also rolling down the hill…

    As I have said in the tl;dr, we are looking for the shortest path, but the start and goal differ for the part 1 and 2. So I have decided to refactor my solution to a BFS algorithm that takes necessary parameters via functions:

    -
    fn bfs<F, G>(
    graph: &[Vec<char>], start: &Position, has_edge: F, is_target: G
    ) -> Option<usize>
    where
    F: Fn(&[Vec<char>], &Position, &Position) -> bool,
    G: Fn(&[Vec<char>], &Position) -> bool
    +
    fn bfs<F, G>(
    graph: &[Vec<char>], start: &Position, has_edge: F, is_target: G
    ) -> Option<usize>
    where
    F: Fn(&[Vec<char>], &Position, &Position) -> bool,
    G: Fn(&[Vec<char>], &Position) -> bool

    We pass the initial vertex from the caller and everything else is left to the BFS algorithm, based on the has_edge and is_target functions.

    This was easy! And that is not very usual in Rust once you want to pass around @@ -1306,7 +1306,7 @@ time complexity, because of the priority heap instead of the queue.

    You can implement a lot of traits if you want to. It is imperative to implement ordering on the packets. I had a typo, so I also proceeded to implement a Display trait for debugging purposes:

    -
    impl Display for Packet {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
    Packet::Integer(x) => write!(f, "{x}"),
    Packet::List(lst) => write!(f, "[{}]", lst.iter().map(|p| format!("{p}")).join(",")),
    }
    }
    }
    +
    impl Display for Packet {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
    Packet::Integer(x) => write!(f, "{x}"),
    Packet::List(lst) => write!(f, "[{}]", lst.iter().map(|p| format!("{p}")).join(",")),
    }
    }
    }

    Solution

    A lot of technical details… Parsing is nasty too…

    Day 14: Regolith Reservoir

    @@ -1326,16 +1326,16 @@ leave it be, so I tried to implement the Index and IndexMutunsafe
    part are the 2 methods that are named *unchecked*. Anyways, I will be implementing the Index* traits for now, rather than the SliceIndex.

    It's relatively straightforward…

    -
    impl<I, C> Index<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    +
    impl<I, C> Index<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for [C]
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }

    We can see a lot of similarities to the implementation of index and index_mut functions. In the end, they are 1:1, just wrapped in the trait that provides a syntax sugar for container[idx].

    note

    I have also switched from using the TryFrom to TryInto trait, since it better matches what we are using, the .try_into rather than usize::try_from.

    Also implementing TryFrom automatically provides you with a TryInto trait, -since it is relatively easy to implement. Just compare the following:

    pub trait TryFrom<T>: Sized {
    type Error;

    fn try_from(value: T) -> Result<Self, Self::Error>;
    }

    pub trait TryInto<T>: Sized {
    type Error;

    fn try_into(self) -> Result<T, Self::Error>;
    }
    +since it is relatively easy to implement. Just compare the following:

    pub trait TryFrom<T>: Sized {
    type Error;

    fn try_from(value: T) -> Result<Self, Self::Error>;
    }

    pub trait TryInto<T>: Sized {
    type Error;

    fn try_into(self) -> Result<T, Self::Error>;
    }

    OK, so we have our trait implemented, we should be able to use container[index], right? Yes… but actually no 😦

    -
    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:26:18
    |
    26 | if trees[pos] > tallest {
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:30:28
    |
    30 | max(tallest, trees[pos])
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<isize>`
    --> src/bin/day08.rs:52:28
    |
    52 | let max_height = trees[position];
    | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<isize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<isize>>`
    +
    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:26:18
    |
    26 | if trees[pos] > tallest {
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<usize>`
    --> src/bin/day08.rs:30:28
    |
    30 | max(tallest, trees[pos])
    | ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<usize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<usize>>`

    error[E0277]: the type `[std::vec::Vec<i8>]` cannot be indexed by `aoc_2022::Vector2D<isize>`
    --> src/bin/day08.rs:52:28
    |
    52 | let max_height = trees[position];
    | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<[std::vec::Vec<i8>]>` is not implemented for `aoc_2022::Vector2D<isize>`
    = note: required for `std::vec::Vec<std::vec::Vec<i8>>` to implement `std::ops::Index<aoc_2022::Vector2D<isize>>`

    Why? We have it implemented for the slices ([C]), why doesn't it work? Well, the fun part consists of the fact that in other place, where we were using it, we were passing the &[Vec<T>], but this is coming from a helper functions that @@ -1345,9 +1345,9 @@ those. Just for the slices. 🤯 What are we going to do about it?

    so let's implement a macro! The only difference across the implementations are the types of the outer containers. Implementation doesn't differ at all!

    Implementing the macro can be done in a following way:

    -
    macro_rules! generate_indices {
    ($container:ty) => {
    impl<I, C> Index<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    };
    }
    +
    macro_rules! generate_indices {
    ($container:ty) => {
    impl<I, C> Index<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: Index<usize>,
    {
    type Output = C::Output;

    fn index(&self, index: Vector2D<I>) -> &Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &self[y][x]
    }
    }

    impl<I, C> IndexMut<Vector2D<I>> for $container
    where
    I: Copy + TryInto<usize>,
    <I as TryInto<usize>>::Error: Debug,
    C: IndexMut<usize>,
    {
    fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
    let (x, y): (usize, usize) =
    (index.x.try_into().unwrap(), index.y.try_into().unwrap());
    &mut self[y][x]
    }
    }
    };
    }

    And now we can simply do

    -
    generate_indices!(VecDeque<C>);
    generate_indices!([C]);
    generate_indices!(Vec<C>);
    // generate_indices!([C; N], const N: usize);
    +
    generate_indices!(VecDeque<C>);
    generate_indices!([C]);
    generate_indices!(Vec<C>);
    // generate_indices!([C; N], const N: usize);

    The last type (I took the inspiration from the implementations of the Index and IndexMut traits) is a bit problematic, because of the const N: usize part, which I haven't managed to be able to parse. And that's how I got rid of the error.

    @@ -1357,11 +1357,11 @@ copy-paste, cause the cost of this “monstrosity” outweighs the benefits of n

    This issue is relatively funny. If you don't use any type aliases, just the raw types, you'll get suggested certain changes by the clippy. For example if you consider the following piece of code

    -
    fn get_sum(nums: &Vec<i32>) -> i32 {
    nums.iter().sum()
    }

    fn main() {
    let nums = vec![1, 2, 3];
    println!("Sum: {}", get_sum(&nums));
    }
    +
    fn get_sum(nums: &Vec<i32>) -> i32 {
    nums.iter().sum()
    }

    fn main() {
    let nums = vec![1, 2, 3];
    println!("Sum: {}", get_sum(&nums));
    }

    and you run clippy on it, you will get

    -
    Checking playground v0.0.1 (/playground)
    warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
    --> src/main.rs:1:18
    |
    1 | fn get_sum(nums: &Vec<i32>) -> i32 {
    | ^^^^^^^^^ help: change this to: `&[i32]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
    = note: `#[warn(clippy::ptr_arg)]` on by default

    warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.61s
    +
    Checking playground v0.0.1 (/playground)
    warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
    --> src/main.rs:1:18
    |
    1 | fn get_sum(nums: &Vec<i32>) -> i32 {
    | ^^^^^^^^^ help: change this to: `&[i32]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
    = note: `#[warn(clippy::ptr_arg)]` on by default

    warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.61s

    However, if you introduce a type alias, such as

    -
    type Numbers = Vec<i32>;
    +
    type Numbers = Vec<i32>;

    Then clippy won't say anything, cause there is literally nothing to suggest. However the outcome is not the same…

    ]]> me+blog@mfocko.xyz (Matej Focko) @@ -1392,10 +1392,10 @@ backpacks and we want to choose the elf that has the most food ;)

    At first I've decided to put asserts into my main, something like

    -
    assert_eq!(part_1(&sample), 24000);
    info!("Part 1: {}", part_1(&input));

    assert_eq!(part_2(&sample), 45000);
    info!("Part 2: {}", part_2(&input));
    +
    assert_eq!(part_1(&sample), 24000);
    info!("Part 1: {}", part_1(&input));

    assert_eq!(part_2(&sample), 45000);
    info!("Part 2: {}", part_2(&input));

    However, once you get further, the sample input may take some time to run itself. So in the end, I have decided to turn them into unit tests:

    -
    #[cfg(test)]
    mod tests {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample = parse_input("samples/day01.txt");
    assert_eq!(part_1(&sample), 24000);
    }

    #[test]
    fn test_part_2() {
    let sample = parse_input("samples/day01.txt");
    assert_eq!(part_2(&sample), 45000);
    }
    }
    +
    #[cfg(test)]
    mod tests {
    use super::*;

    #[test]
    fn test_part_1() {
    let sample = parse_input("samples/day01.txt");
    assert_eq!(part_1(&sample), 24000);
    }

    #[test]
    fn test_part_2() {
    let sample = parse_input("samples/day01.txt");
    assert_eq!(part_2(&sample), 45000);
    }
    }

    And later on I have noticed, it's hard to tell the difference between the days, so I further renamed the mod from generic tests to reflect the days.

    Also after finishing the first day puzzle, I have installed an sccache to @@ -1424,16 +1424,16 @@ to give up. Let's dive into it \o/

    Fun fact

    Fighting the compiler took me 30 minutes.

    We need to find a common item among 2 collections, that's an easy task, right? We can construct 2 sets and find an intersection:

    -
    let top: HashSet<i32> = [1, 2, 3].iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5].iter().collect();
    +
    let top: HashSet<i32> = [1, 2, 3].iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5].iter().collect();

    Now, the first issue that we encounter is caused by the fact that we are using a slice (the […]), iterator of that returns references to the numbers. And we get immediately yelled at by the compiler, because the numbers are discarded after running the .collect. To fix this, we can use .into_iter:

    -
    let top: HashSet<i32> = [1, 2, 3].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5].into_iter().collect();
    +
    let top: HashSet<i32> = [1, 2, 3].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5].into_iter().collect();

    This way the numbers will get copied instead of referenced. OK, let's find the intersection of those 2 collections:

    -
    println!("Common elements: {:?}", top.intersection(&bottom));
    -
    Common elements: [3]
    +
    println!("Common elements: {:?}", top.intersection(&bottom));
    +
    Common elements: [3]
    caution

    Notice that we need to do &bottom. It explicitly specifies that .intersection borrows the bottom, i.e. takes an immutable reference to it.

    That's what we want, right? Looks like it! \o/

    @@ -1441,16 +1441,16 @@ intersection of those 2 collections:

    that should be fairly easy, we have an intersection and we want to find intersection over all of them.

    Let's have a look at the type of the .intersection

    -
    pub fn intersection<'a>(
        &'a self,
        other: &'a HashSet<T, S>
    ) -> Intersection<'a, T, S>
    +
    pub fn intersection<'a>(
        &'a self,
        other: &'a HashSet<T, S>
    ) -> Intersection<'a, T, S>

    OK… Huh… But we have an example there!

    -
    let intersection: HashSet<_> = a.intersection(&b).collect();
    +
    let intersection: HashSet<_> = a.intersection(&b).collect();

    Cool, that's all we need.

    -
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).collect();
    println!("Intersection: {:?}", intersection);
    -
    Intersection: {3, 4}
    +
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).collect();
    println!("Intersection: {:?}", intersection);
    +
    Intersection: {3, 4}

    Cool, so let's do the intersection with the top_2:

    -
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).collect();
    let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
    println!("Intersection: {:?}", intersection);
    +
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).collect();
    let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
    println!("Intersection: {:?}", intersection);

    And we get yelled at by the compiler:

    -
    error[E0308]: mismatched types
    --> src/main.rs:10:58
    |
    10 | let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
    | ------------ ^^^^^^ expected `&i32`, found `i32`
    | |
    | arguments to this function are incorrect
    |
    = note: expected reference `&HashSet<&i32>`
    found reference `&HashSet<i32>`
    +
    error[E0308]: mismatched types
    --> src/main.rs:10:58
    |
    10 | let intersection: HashSet<_> = intersection.intersection(&top_2).collect();
    | ------------ ^^^^^^ expected `&i32`, found `i32`
    | |
    | arguments to this function are incorrect
    |
    = note: expected reference `&HashSet<&i32>`
    found reference `&HashSet<i32>`

    /o\ What the hell is going on here? Well, the funny thing is, that this operation doesn't return the elements themselves, but the references to them and when we pass the third set, it has just the values themselves, without any references.

    @@ -1460,8 +1460,8 @@ a “tax” for having a borrow checker drilling your ass having your making sure you're not doing something naughty that may cause an undefined behavior.

    To resolve this we need to get an iterator that clones the elements:

    -
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).cloned().collect();
    let intersection: HashSet<_> = intersection.intersection(&top_2).cloned().collect();
    let intersection: HashSet<_> = intersection.intersection(&bottom_2).cloned().collect();
    println!("Intersection: {:?}", intersection);
    -
    Intersection: {4}
    +
    let top: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let bottom: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
    let top_2: HashSet<i32> = [2, 3, 4, 5, 6].into_iter().collect();
    let bottom_2: HashSet<i32> = [4, 5, 6].into_iter().collect();

    let intersection: HashSet<_> = top.intersection(&bottom).cloned().collect();
    let intersection: HashSet<_> = intersection.intersection(&top_2).cloned().collect();
    let intersection: HashSet<_> = intersection.intersection(&bottom_2).cloned().collect();
    println!("Intersection: {:?}", intersection);
    +
    Intersection: {4}

    Solution

    The approach is pretty simple, if you omit the 1on1 with the compiler. You just have some fun with the set operations :)

    @@ -1475,7 +1475,7 @@ Find how many overlap and can take the day off.

    Day 5: Supply Stacks

    tl;dr

    Let's play with stacks of crates.

    Very easy problem with very annoying input. You can judge yourself:

    -
        [D]
    [N] [C]
    [Z] [M] [P]
    1 2 3

    move 1 from 2 to 1
    move 3 from 1 to 3
    move 2 from 2 to 1
    move 1 from 1 to 2
    +
        [D]
    [N] [C]
    [Z] [M] [P]
    1 2 3

    move 1 from 2 to 1
    move 3 from 1 to 3
    move 2 from 2 to 1
    move 1 from 1 to 2

    Good luck transforming that into something reasonable :)

    Fun fact

    Took me 40 minutes to parse this reasonably, including fighting the compiler.

    Solution

    @@ -1483,7 +1483,7 @@ Find how many overlap and can take the day off.

    the work. Later on I have decided to explore the std and interface of the std::vec::Vec and found split_off which takes an index and splits (duh) the vector:

    -
    let mut vec = vec![1, 2, 3];
    let vec2 = vec.split_off(1);
    assert_eq!(vec, [1]);
    assert_eq!(vec2, [2, 3]);
    +
    let mut vec = vec![1, 2, 3];
    let vec2 = vec.split_off(1);
    assert_eq!(vec, [1]);
    assert_eq!(vec2, [2, 3]);

    This helped me simplify my solution a lot and also get rid of some edge cases.

    Day 6: Tuning Trouble

    tl;dr

    Finding start of the message in a very weird protocol. Start of the message is @@ -1508,7 +1508,7 @@ directories that take a lot of space and should be deleted.

    Solution

    We need to “build” a file system from the input that is given in a following form:

    -
    $ cd /
    $ ls
    dir a
    14848514 b.txt
    8504156 c.dat
    dir d
    $ cd a
    $ ls
    dir e
    29116 f
    2557 g
    62596 h.lst
    $ cd e
    $ ls
    584 i
    $ cd ..
    $ cd ..
    $ cd d
    $ ls
    4060174 j
    8033020 d.log
    5626152 d.ext
    7214296 k
    +
    $ cd /
    $ ls
    dir a
    14848514 b.txt
    8504156 c.dat
    dir d
    $ cd a
    $ ls
    dir e
    29116 f
    2557 g
    62596 h.lst
    $ cd e
    $ ls
    584 i
    $ cd ..
    $ cd ..
    $ cd d
    $ ls
    4060174 j
    8033020 d.log
    5626152 d.ext
    7214296 k

    There are few ways in which you can achieve this and also you can assume some preconditions, but why would we do that, right? :)

    You can “slap” this in either HashMap or BTreeMap and call it a day. @@ -1528,7 +1528,7 @@ references are present) are checked dynamically.

    So in the end, if you wan to have Rc<RefCell<T>>.

    So, how are we going to represent the file system then? We will use an enumeration, hehe, which is an algebraic data type that can store some stuff in itself 😩

    -
    type FileHandle = Rc<RefCell<AocFile>>;

    #[derive(Debug)]
    enum AocFile {
    File(usize),
    Directory(BTreeMap<String, FileHandle>),
    }
    +
    type FileHandle = Rc<RefCell<AocFile>>;

    #[derive(Debug)]
    enum AocFile {
    File(usize),
    Directory(BTreeMap<String, FileHandle>),
    }

    Let's go over it! FileHandle represents dynamically allocated AocFile, not much to discuss. What does the #[derive(Debug)] do though? It lets us to print out the value of that enumeration, it's derived, so it's not as good as if we had @@ -1626,15 +1626,15 @@ problems in it. However the toolkit is questionable :/

    with rust-analyzer. Because of my choice of libraries, we will also introduce a .envrc file that can be used by direnv, which allows you to set specific environment variables when you enter a directory. In our case, we will use

    -
    # to show nice backtrace when using the color-eyre
    export RUST_BACKTRACE=1

    # to catch logs generated by tracing
    export RUST_LOG=trace
    +
    # to show nice backtrace when using the color-eyre
    export RUST_BACKTRACE=1

    # to catch logs generated by tracing
    export RUST_LOG=trace

    And for the one of the most obnoxious things ever, we will use a script to download the inputs instead of “clicking, opening and copying to a file1. There is no need to be fancy, so we will adjust Python script by Martin2.

    -
    #!/usr/bin/env python3

    import datetime
    import yaml
    import requests
    import sys


    def load_config():
    with open("env.yaml", "r") as f:
    js = yaml.load(f, Loader=yaml.Loader)
    return js["session"], js["year"]


    def get_input(session, year, day):
    return requests.get(
    f"https://adventofcode.com/{year}/day/{day}/input",
    cookies={"session": session},
    headers={
    "User-Agent": "{repo} by {mail}".format(
    repo="gitlab.com/mfocko/advent-of-code-2022",
    mail="me@mfocko.xyz",
    )
    },
    ).content.decode("utf-8")


    def main():
    day = datetime.datetime.now().day
    if len(sys.argv) == 2:
    day = sys.argv[1]

    session, year = load_config()
    problem_input = get_input(session, year, day)

    with open(f"./inputs/day{day:>02}.txt", "w") as f:
    f.write(problem_input)


    if __name__ == "__main__":
    main()
    +
    #!/usr/bin/env python3

    import datetime
    import yaml
    import requests
    import sys


    def load_config():
    with open("env.yaml", "r") as f:
    js = yaml.load(f, Loader=yaml.Loader)
    return js["session"], js["year"]


    def get_input(session, year, day):
    return requests.get(
    f"https://adventofcode.com/{year}/day/{day}/input",
    cookies={"session": session},
    headers={
    "User-Agent": "{repo} by {mail}".format(
    repo="gitlab.com/mfocko/advent-of-code-2022",
    mail="me@mfocko.xyz",
    )
    },
    ).content.decode("utf-8")


    def main():
    day = datetime.datetime.now().day
    if len(sys.argv) == 2:
    day = sys.argv[1]

    session, year = load_config()
    problem_input = get_input(session, year, day)

    with open(f"./inputs/day{day:>02}.txt", "w") as f:
    f.write(problem_input)


    if __name__ == "__main__":
    main()

    If the script is called without any arguments, it will deduce the day from the system, so we do not need to change the day every morning. It also requires a configuration file:

    -
    # env.yaml
    session: ‹your session cookie›
    year: 2022
    +
    # env.yaml
    session: ‹your session cookie›
    year: 2022

    Libraries

    Looking at the list of the libraries, I have chosen “a lot” of them. Let's walk through each of them.

    @@ -1663,7 +1663,7 @@ also we can follow KISS. I have 2 modules that my “library” exports parsing and one for 2D vector (that gets used quite often during Advent of Code).

    Key part is, of course, processing the input and my library exports following functions that get used a lot:

    -
    /// Reads file to the string.
    pub fn file_to_string<P: AsRef<Path>>(pathname: P) -> String;

    /// Reads file and returns it as a vector of characters.
    pub fn file_to_chars<P: AsRef<Path>>(pathname: P) -> Vec<char>;

    /// Reads file and returns a vector of parsed structures. Expects each structure
    /// on its own line in the file. And `T` needs to implement `FromStr` trait.
    pub fn file_to_structs<P: AsRef<Path>, T: FromStr>(pathname: P) -> Vec<T>
    where
    <T as FromStr>::Err: Debug;

    /// Converts iterator over strings to a vector of parsed structures. `T` needs
    /// to implement `FromStr` trait and its error must derive `Debug` trait.
    pub fn strings_to_structs<T: FromStr, U>(
    iter: impl Iterator<Item = U>
    ) -> Vec<T>
    where
    <T as std::str::FromStr>::Err: std::fmt::Debug,
    U: Deref<Target = str>;

    /// Reads file and returns it as a vector of its lines.
    pub fn file_to_lines<P: AsRef<Path>>(pathname: P) -> Vec<String>;
    +
    /// Reads file to the string.
    pub fn file_to_string<P: AsRef<Path>>(pathname: P) -> String;

    /// Reads file and returns it as a vector of characters.
    pub fn file_to_chars<P: AsRef<Path>>(pathname: P) -> Vec<char>;

    /// Reads file and returns a vector of parsed structures. Expects each structure
    /// on its own line in the file. And `T` needs to implement `FromStr` trait.
    pub fn file_to_structs<P: AsRef<Path>, T: FromStr>(pathname: P) -> Vec<T>
    where
    <T as FromStr>::Err: Debug;

    /// Converts iterator over strings to a vector of parsed structures. `T` needs
    /// to implement `FromStr` trait and its error must derive `Debug` trait.
    pub fn strings_to_structs<T: FromStr, U>(
    iter: impl Iterator<Item = U>
    ) -> Vec<T>
    where
    <T as std::str::FromStr>::Err: std::fmt::Debug,
    U: Deref<Target = str>;

    /// Reads file and returns it as a vector of its lines.
    pub fn file_to_lines<P: AsRef<Path>>(pathname: P) -> Vec<String>;

    As for the vector, I went with a rather simple implementation that allows only addition of the vectors for now and accessing the elements via functions x() and y(). Also the vector is generic, so we can use it with any numeric type we @@ -1672,36 +1672,36 @@ need.

    We can also prepare a template to quickly bootstrap each of the days. We know that each puzzle has 2 parts, which means that we can start with 2 functions that will solve them.

    -
    fn part1(input: &Input) -> Output {
    todo!()
    }

    fn part2(input: &Input) -> Output {
    todo!()
    }
    +
    fn part1(input: &Input) -> Output {
    todo!()
    }

    fn part2(input: &Input) -> Output {
    todo!()
    }

    Both functions take reference to the input and return some output (in majority of puzzles, it is the same type). todo!() can be used as a nice placeholder, it also causes a panic when reached and we could also provide some string with an explanation, e.g. todo!("part 1"). We have not given functions a specific type and to avoid as much copy-paste as possible, we will introduce type aliases.

    -
    type Input = String;
    type Output = i32;
    +
    type Input = String;
    type Output = i32;
    tip

    This allows us to quickly adjust the types only in one place without the need to do regex-replace or replace them manually.

    For each day we get a personalized input that is provided as a text file. Almost all the time, we would like to get some structured type out of that input, and therefore it makes sense to introduce a new function that will provide the parsing of the input.

    -
    fn parse_input(path: &str) -> Input {
    todo!()
    }
    +
    fn parse_input(path: &str) -> Input {
    todo!()
    }

    This “parser” will take a path to the file, just in case we would like to run the sample instead of input.

    OK, so now we can write a main function that will take all of the pieces and run them.

    -
    fn main() {
    let input = parse_input("inputs/dayXX.txt");

    println!("Part 1: {}", part_1(&input));
    println!("Part 2: {}", part_2(&input));
    }
    +
    fn main() {
    let input = parse_input("inputs/dayXX.txt");

    println!("Part 1: {}", part_1(&input));
    println!("Part 2: {}", part_2(&input));
    }

    This would definitely do :) But we have installed a few libraries and we want to use them. In this part we are going to utilize tracing (for tracing, duh…) and color-eyre (for better error reporting, e.g. from parsing).

    -
    fn main() -> Result<()> {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = parse_input("inputs/dayXX.txt");

    info!("Part 1: {}", part_1(&input));
    info!("Part 2: {}", part_2(&input));

    Ok(())
    }
    +
    fn main() -> Result<()> {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = parse_input("inputs/dayXX.txt");

    info!("Part 1: {}", part_1(&input));
    info!("Part 2: {}", part_2(&input));

    Ok(())
    }

    The first statement will set up tracing and configure it to print out the logs to terminal, based on the environment variable. We also change the formatting a bit, since we do not need all the fancy features of the logger. Pure initialization would get us logs like this:

    -
    2022-12-11T19:53:19.975343Z  INFO day01: Part 1: 0
    +
    2022-12-11T19:53:19.975343Z  INFO day01: Part 1: 0

    However after running that command, we will get the following:

    -
     INFO src/bin/day01.rs:35: Part 1: 0
    +
     INFO src/bin/day01.rs:35: Part 1: 0

    And the color_eyre::install()? is quite straightforward. We just initialize the error reporting by color eyre.

    caution

    Notice that we had to add Ok(()) to the end of the function and adjust the @@ -1709,7 +1709,7 @@ return type of the main to Result<()>. It is cau can be installed only once and therefore it can fail, that is how we got the ? at the end of the ::install which unwraps the »result« of the installation.

    Overall we will get to a template like this:

    -
    use aoc_2022::*;

    use color_eyre::eyre::Result;
    use tracing::info;
    use tracing_subscriber::EnvFilter;

    type Input = String;
    type Output = i32;

    fn parse_input(path: &str) -> Input {
    todo!()
    }

    fn part1(input: &Input) -> Output {
    todo!()
    }

    fn part2(input: &Input) -> Output {
    todo!()
    }

    fn main() -> Result<()> {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = parse_input("inputs/dayXX.txt");

    info!("Part 1: {}", part_1(&input));
    info!("Part 2: {}", part_2(&input));

    Ok(())
    }
    +
    use aoc_2022::*;

    use color_eyre::eyre::Result;
    use tracing::info;
    use tracing_subscriber::EnvFilter;

    type Input = String;
    type Output = i32;

    fn parse_input(path: &str) -> Input {
    todo!()
    }

    fn part1(input: &Input) -> Output {
    todo!()
    }

    fn part2(input: &Input) -> Output {
    todo!()
    }

    fn main() -> Result<()> {
    tracing_subscriber::fmt()
    .with_env_filter(EnvFilter::from_default_env())
    .with_target(false)
    .with_file(true)
    .with_line_number(true)
    .without_time()
    .compact()
    .init();
    color_eyre::install()?;

    let input = parse_input("inputs/dayXX.txt");

    info!("Part 1: {}", part_1(&input));
    info!("Part 2: {}", part_2(&input));

    Ok(())
    }

    Footnotes

    1. diff --git a/blog/tags/admin/index.html b/blog/tags/admin/index.html index 1da2b10..42f002c 100644 --- a/blog/tags/admin/index.html +++ b/blog/tags/admin/index.html @@ -14,8 +14,8 @@ - - + +

      One post tagged with "admin"

      View All Tags

      · 4 min read
      Matej Focko

      When you decide to run Fedora on your VPS, you might get screwed over by using diff --git a/blog/tags/advent-of-code-2022/index.html b/blog/tags/advent-of-code-2022/index.html index fab2ae3..df4a9d4 100644 --- a/blog/tags/advent-of-code-2022/index.html +++ b/blog/tags/advent-of-code-2022/index.html @@ -14,8 +14,8 @@ - - + +

      5 posts tagged with "advent-of-code-2022"

      View All Tags
      diff --git a/blog/tags/advent-of-code/index.html b/blog/tags/advent-of-code/index.html index b05a7ee..38717c0 100644 --- a/blog/tags/advent-of-code/index.html +++ b/blog/tags/advent-of-code/index.html @@ -14,8 +14,8 @@ - - + +

      5 posts tagged with "advent-of-code"

      View All Tags
      diff --git a/blog/tags/copr/index.html b/blog/tags/copr/index.html index d631f1e..0ea2ab0 100644 --- a/blog/tags/copr/index.html +++ b/blog/tags/copr/index.html @@ -14,8 +14,8 @@ - - + +

      One post tagged with "copr"

      View All Tags

      · 4 min read
      Matej Focko

      When you decide to run Fedora on your VPS, you might get screwed over by using diff --git a/blog/tags/cpp/index.html b/blog/tags/cpp/index.html index 6ab92e7..bf05ad7 100644 --- a/blog/tags/cpp/index.html +++ b/blog/tags/cpp/index.html @@ -14,8 +14,8 @@ - - + +

      One post tagged with "cpp"

      View All Tags

      · 17 min read
      Matej Focko

      Let's try to solve one of the LeetCode challenges in easy and hard mode at the diff --git a/blog/tags/cult/index.html b/blog/tags/cult/index.html index a5ae071..0c22ddc 100644 --- a/blog/tags/cult/index.html +++ b/blog/tags/cult/index.html @@ -14,8 +14,8 @@ - - + +

      One post tagged with "cult"

      View All Tags
      - - + +

      One post tagged with "hype"

      View All Tags
      - - + + diff --git a/blog/tags/iterators/index.html b/blog/tags/iterators/index.html index 39124cc..696ad1b 100644 --- a/blog/tags/iterators/index.html +++ b/blog/tags/iterators/index.html @@ -14,8 +14,8 @@ - - + +

      One post tagged with "iterators"

      View All Tags

      · 17 min read
      Matej Focko

      Let's try to solve one of the LeetCode challenges in easy and hard mode at the diff --git a/blog/tags/leetcode/index.html b/blog/tags/leetcode/index.html index 5052da0..52d2ed8 100644 --- a/blog/tags/leetcode/index.html +++ b/blog/tags/leetcode/index.html @@ -14,8 +14,8 @@ - - + +

      One post tagged with "leetcode"

      View All Tags

      · 17 min read
      Matej Focko

      Let's try to solve one of the LeetCode challenges in easy and hard mode at the diff --git a/blog/tags/memory-safety/index.html b/blog/tags/memory-safety/index.html index 149a0a5..4bbe5e5 100644 --- a/blog/tags/memory-safety/index.html +++ b/blog/tags/memory-safety/index.html @@ -14,8 +14,8 @@ - - + +

      One post tagged with "memory safety"

      View All Tags
      - - + +

      One post tagged with "red-hat"

      View All Tags

      · 4 min read
      Matej Focko

      When you decide to run Fedora on your VPS, you might get screwed over by using diff --git a/blog/tags/rust/index.html b/blog/tags/rust/index.html index 59521e6..122da01 100644 --- a/blog/tags/rust/index.html +++ b/blog/tags/rust/index.html @@ -14,8 +14,8 @@ - - + +

      6 posts tagged with "rust"

      View All Tags
      - - + +

      One post tagged with "vps"

      View All Tags

      · 4 min read
      Matej Focko

      When you decide to run Fedora on your VPS, you might get screwed over by using diff --git a/blog/tags/🏭/index.html b/blog/tags/🏭/index.html index c909ac6..0c74cab 100644 --- a/blog/tags/🏭/index.html +++ b/blog/tags/🏭/index.html @@ -14,8 +14,8 @@ - - + +

      One post tagged with "🏭"

      View All Tags

      · 4 min read
      Matej Focko

      When you decide to run Fedora on your VPS, you might get screwed over by using diff --git a/c/bonuses/seminar-03/index.html b/c/bonuses/seminar-03/index.html index f34a7c1..e379696 100644 --- a/c/bonuses/seminar-03/index.html +++ b/c/bonuses/seminar-03/index.html @@ -16,8 +16,8 @@ - - + +

      3rd seminar

      caution

      Deadline for the submission of the bonus is March 16th 24:00.

      @@ -51,7 +51,7 @@ it.

      Function pointers

      In the skeleton of the “full fat” version you might have noticed a weird type signature of both the maximum and select_sort functions. Those functions get passed a function pointer to the comparator that you use for comparing the -respective elements in the passed in array.

      If we take the parameter from one of the functions from the skeleton:

      int (*comp)(const void *, const void *)

      comp is a function pointer to a function that takes two pointers of unspecified +respective elements in the passed in array.

      If we take the parameter from one of the functions from the skeleton:

      int (*comp)(const void *, const void *)

      comp is a function pointer to a function that takes two pointers of unspecified type, i.e. pure address to the memory (you don't know what stored in there), and returns an int.

      You can pass the function by simply using its name. (There is no need to use & to get its address.) And you can also call the function by “calling” the function @@ -66,6 +66,6 @@ submitting the homeworks, that is:

    2. Create a MR to the main branch with me (@xfocko) as the reviewer.
    Directory structure for bonuses

    Ideally create a directory seminar-bonuses in the root of your repository with -bonuses in their own subdirectories.

    Structure of your repository can look like this:

    .
    ├── bonuses
    │ └── seminar-03
    ├── hello
    ├── hw01
    ├── hw02
    ├── seminar-01
    ├── seminar-02
    └── seminar-03

    or

    .
    ├── bonus-seminar-03
    ├── hello
    ├── hw01
    ├── hw02
    ├── seminar-01
    ├── seminar-02
    └── seminar-03

    Structure of the bonuses is entirely up to you, just keep it consistent.

    +bonuses in their own subdirectories.

    Structure of your repository can look like this:

    .
    ├── bonuses
    │ └── seminar-03
    ├── hello
    ├── hw01
    ├── hw02
    ├── seminar-01
    ├── seminar-02
    └── seminar-03

    or

    .
    ├── bonus-seminar-03
    ├── hello
    ├── hw01
    ├── hw02
    ├── seminar-01
    ├── seminar-02
    └── seminar-03

    Structure of the bonuses is entirely up to you, just keep it consistent.

    \ No newline at end of file diff --git a/c/bonuses/seminar-04/index.html b/c/bonuses/seminar-04/index.html index 3a4e6bc..8d1e579 100644 --- a/c/bonuses/seminar-04/index.html +++ b/c/bonuses/seminar-04/index.html @@ -16,8 +16,8 @@ - - + +

    4th seminar

    caution

    Deadline for the submission of the bonus is March 23th 24:00.

    @@ -54,7 +54,7 @@ for the implementation of this task it is much easier to use just the pointers.<

    Example of run

    For a better understanding of your task, I will describe a simple walk with corresponding function call.

    -
    const char *map = (
    ">.v"
    ".K<"
    "..."
    );

    walk(map, &map[6], '^', 3, 3);
    +
    const char *map = (
    ">.v"
    ".K<"
    "..."
    );

    walk(map, &map[6], '^', 3, 3);

    For this call, you should return FOUND_KEY. Let us walk through the walk ;)

    1. @@ -62,31 +62,31 @@ function call.

      he follows the direction given by parameter (upwards, denoted as N(orth), so that we can differentiate markers on the map with the robot when using printing function).

      -
      >.v
      .K<
      N..
      +
      >.v
      .K<
      N..
    2. Moves up:

      -
      >.v
      NK<
      ...
      +
      >.v
      NK<
      ...
    3. Moves up (now covers >), changes direction to right:

      -
      E.v
      .K<
      ...
      +
      E.v
      .K<
      ...
    4. Moves to right:

      -
      >Ev
      .K<
      ...
      +
      >Ev
      .K<
      ...
    5. Moves to right, faces south:

      -
      >.S
      .K<
      ...
      +
      >.S
      .K<
      ...
    6. Moves down, faces west:

      -
      >.v
      .KW
      ...
      +
      >.v
      .KW
      ...
    7. Moves left, founds key, returns FOUND_KEY:

      -
      >.v
      .W<
      ...
      +
      >.v
      .W<
      ...

    Bonus part

    diff --git a/c/bonuses/seminar-05-06/index.html b/c/bonuses/seminar-05-06/index.html index badb65c..1d7d23e 100644 --- a/c/bonuses/seminar-05-06/index.html +++ b/c/bonuses/seminar-05-06/index.html @@ -16,8 +16,8 @@ - - + +

    5th and 6th seminar

    For this bonus you can get at maximum 2.5 K₡.

    @@ -30,7 +30,7 @@ implementing a very special cipher.

    string in reversed order (also uppercase).

    In case you are given NULL, return NULL.

    Example (more in tests):

    -
    char* reversed = reverse("Hello world!");

    printf("%s\n", reversed);
    // "!DLROW OLLEH"

    if (reversed != NULL) {
    free(reversed);
    }
    +
    char* reversed = reverse("Hello world!");

    printf("%s\n", reversed);
    // "!DLROW OLLEH"

    if (reversed != NULL) {
    free(reversed);
    }

    Task no. 2: Vigenère (0.5 K₡)

    Vigenère cipher is similar to the Caesar cipher, but you also have a key that is used for encrypting (or decrypting).

    @@ -50,7 +50,7 @@ are uppercase or lowercase.

    Function returns address of the encrypted (or decrypted) string. Or NULL in case error occurs.

    Example:

    -
    char *encrypted = vigenere_encrypt("CoMPuTeR", "Hello world!");

    printf("%s\n", encrypted);
    // "JSXAI PSINR!"

    if (encrypted != NULL) {
    free(encrypted)
    }
    +
    char *encrypted = vigenere_encrypt("CoMPuTeR", "Hello world!");

    printf("%s\n", encrypted);
    // "JSXAI PSINR!"

    if (encrypted != NULL) {
    free(encrypted)
    }

    Bonus part (0.5 K₡)

    If you can utilize helper function that would do both encrypting and decrypting, you can gain 0.5 K₡.

    @@ -82,7 +82,7 @@ so we will demonstrate on letter H:

  • That half is used for xor with the other 4 bits:

    -
        1000  // second half
    XOR 1000 // first half after 2nd step
    --------
    0000
    +
        1000  // second half
    XOR 1000 // first half after 2nd step
    --------
    0000
  • Now we combine both halves (first one is 1000, which we got from the 2nd step @@ -97,7 +97,7 @@ which is encrypted character H using this method.

  • char* bit_decrypt(const unsigned char* text)
  • Example:

    -
    unsigned char* encrypted = bit_encrypt("Hello world!");

    for (int i = 0; i < 12;i++) {
    printf("%x ", encrypted[i]);
    //80 9c 95 95 96 11 bc 96 b9 95 9d 10
    }

    if (encrypted != NULL) {
    free(encrypted);
    }
    +
    unsigned char* encrypted = bit_encrypt("Hello world!");

    for (int i = 0; i < 12;i++) {
    printf("%x ", encrypted[i]);
    //80 9c 95 95 96 11 bc 96 b9 95 9d 10
    }

    if (encrypted != NULL) {
    free(encrypted);
    }

    Task no. 4: All combined to BMP (0.5 K₡)

    Authors of the BMP cipher are non-disclosed :)

    Create pair of functions:

    @@ -114,6 +114,6 @@ which is encrypted character H using this method.

    For decrypting, reverse the steps.

    Submitting

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

    -
    +
    \ No newline at end of file diff --git a/c/bonuses/seminar-08/index.html b/c/bonuses/seminar-08/index.html index ef8102f..e8c1f12 100644 --- a/c/bonuses/seminar-08/index.html +++ b/c/bonuses/seminar-08/index.html @@ -16,8 +16,8 @@ - - + +

    8th seminar bonus assignment

    @@ -46,7 +46,7 @@ take up the space.

    Your first task is to make smallish program that counts occurences of specific (or given) word from file and writes the number to other file.

    Usage of the program is:

    -
    Usage: ./counting <input-file> <output-file> [string-to-be-counted]
    +
    Usage: ./counting <input-file> <output-file> [string-to-be-counted]

    Arguments that are passed to the program represent:

    • <input-file> - path to the file where we count the words
    • @@ -84,16 +84,16 @@ as an argument and pretty-prints it.

      or nil. Why would we have nil in a file? The file represents pre-order iteration through the tree. Leaves never have rank different than 0, so you can safely assume 2 non-existing nils in the input after you read such node ;)

      -
      Example input fileTree it represents
      8;4
      5;3
      3;2
      2;1
      1;0
      nil
      4;0
      7;1
      6;0
      nil
      11;2
      10;1
      9;0
      nil
      12;0

      tree

      +
      Example input fileTree it represents
      8;4
      5;3
      3;2
      2;1
      1;0
      nil
      4;0
      7;1
      6;0
      nil
      11;2
      10;1
      9;0
      nil
      12;0

      tree

      In this task you are only provided with different trees in the test-trees directory. Implementation and format of the pretty-print is totally up to you. :)

      Example of mine for the tree above:

      -
      8 (rank = 4)
      +-- 5 (rank = 3)
      | +-- 3 (rank = 2)
      | | +-- 2 (rank = 1)
      | | | +-- 1 (rank = 0)
      | | +-- 4 (rank = 0)
      | +-- 7 (rank = 1)
      | +-- 6 (rank = 0)
      +-- 11 (rank = 2)
      +-- 10 (rank = 1)
      | +-- 9 (rank = 0)
      +-- 12 (rank = 0)
      +
      8 (rank = 4)
      +-- 5 (rank = 3)
      | +-- 3 (rank = 2)
      | | +-- 2 (rank = 1)
      | | | +-- 1 (rank = 0)
      | | +-- 4 (rank = 0)
      | +-- 7 (rank = 1)
      | +-- 6 (rank = 0)
      +-- 11 (rank = 2)
      +-- 10 (rank = 1)
      | +-- 9 (rank = 0)
      +-- 12 (rank = 0)

      Can you find out what are those trees? :)

      Submitting

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

      -
    +
    \ No newline at end of file diff --git a/c/bonuses/seminar-10/index.html b/c/bonuses/seminar-10/index.html index 891cc5b..4c9a6ca 100644 --- a/c/bonuses/seminar-10/index.html +++ b/c/bonuses/seminar-10/index.html @@ -16,8 +16,8 @@ - - + +

    10th seminar

    Source

    @@ -39,14 +39,14 @@ of that, there are 2 kinds of tests:

    • Unit tests - that are present in test_hangman.c and can be run via:

      -
      $ make check-unit
      +
      $ make check-unit

      They cover majorly functions that can be tested easily via testing framework.

    • Functional tests - same as in seminar-08 and are focused on testing the program as whole. Basic smoke test is already included in usage test case.

      They can be run via:

      -
      $ make check-functional
      +
      $ make check-functional

      When testing hangman function (the game loop), it is suggested to create functional tests.

      When submitting the files for review, please leave out functional tests that @@ -56,7 +56,7 @@ will drag the common files myself. :)

    Whole test suite can be run via:

    -
    $ make check
    +
    $ make check

    Summary of the gameplay

      @@ -89,7 +89,7 @@ bugs. Therefore try to follow this succession of steps:

      In case you are submitting the bonus via GitLab, it is helpful to commit tests before commiting the fixes, so that it is apparent that the bug is manifested. Example of git log (notice that the first line represents latest commit):

      -
      feat: Implement fizz_buzzer
      test: Add tests for fizz_buzzer
      fix: Fix NULL-check in print_name
      test: Add test for NULL in print_name
      +
      feat: Implement fizz_buzzer
      test: Add tests for fizz_buzzer
      fix: Fix NULL-check in print_name
      test: Add test for NULL in print_name

      Tasks

      As to your tasks, there are multiple things wrong in this project.

        @@ -136,6 +136,6 @@ it is a not requirement at all and you can still get all points for the bonus ;)

        Submitting

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

        -
    +
    \ No newline at end of file diff --git a/c/category/bonuses/index.html b/c/category/bonuses/index.html index 68ca881..cea465e 100644 --- a/c/category/bonuses/index.html +++ b/c/category/bonuses/index.html @@ -16,8 +16,8 @@ - - + +

    Bonuses

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

    Practice Exams

    Practice exams for training for the final exam. diff --git a/c/index.html b/c/index.html index a0129e9..c52b363 100644 --- a/c/index.html +++ b/c/index.html @@ -14,10 +14,10 @@ - - + + -

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

    Submitting merge requests for review

    @@ -36,7 +36,7 @@ repository is clean and you are present on the main branch (master, trunk). If you do not know what your default branch is, it is probably master and you should not be on any other branch.

    Output of the command should look like this:

    -
    aisa$ git status
    On branch master # Or main or trunk.
    Your branch is up to date with 'origin/master'.

    nothing to commit, working tree clean
    +
    aisa$ git status
    On branch master # Or main or trunk.
    Your branch is up to date with 'origin/master'.

    nothing to commit, working tree clean

    In case you are on different branch or there are uncommitted changes, do not continue!!! Clean your repository (commit the changes or discard @@ -44,19 +44,19 @@ them), before you continue.

    Step #2 - Create new branch

    In your repository write command:

    -
    aisa$ git checkout -b BRANCH
    Switched to a new branch 'BRANCH'
    +
    aisa$ git checkout -b BRANCH
    Switched to a new branch 'BRANCH'

    Instead of BRANCH use some reasonable name for the branch. For example if you are working on the seminar from 3rd week, name the branch seminar-03.

    Step #3 - Do the assignment

    Download the skeleton for the seminar assignment, extract and program. For example if you are working on 3rd seminar, you can do so by:

    -
    aisa$ wget https://www.fi.muni.cz/pb071/seminars/seminar-03/pb071-seminar-03.zip
    aisa$ unzip pb071-seminar-03.zip
    # Now you should have directory 'seminar-03'.
    aisa$ rm pb071-seminar-03.zip
    aisa$ cd seminar-03
    # You can work on the assignment.
    +
    aisa$ wget https://www.fi.muni.cz/pb071/seminars/seminar-03/pb071-seminar-03.zip
    aisa$ unzip pb071-seminar-03.zip
    # Now you should have directory 'seminar-03'.
    aisa$ rm pb071-seminar-03.zip
    aisa$ cd seminar-03
    # You can work on the assignment.

    Step #4 - Commit and upload the changes to GitLab

    The same way you add and commit files for the homework assignments, you do for the seminar.

    Now you can upload the changes to GitLab. git push is not enough, since repository on GitLab does not know your new branch. You can solve this by adding arguments:

    -
    aisa$ git push origin BRANCH
    ...
    remote: To create a merge request for BRANCH, visit:
    remote: https://gitlab.fi.muni.cz/login/pb071/merge_requests/new?merge_request%5Bsource_branch%5D=BRANCH
    ...
    +
    aisa$ git push origin BRANCH
    ...
    remote: To create a merge request for BRANCH, visit:
    remote: https://gitlab.fi.muni.cz/login/pb071/merge_requests/new?merge_request%5Bsource_branch%5D=BRANCH
    ...

    In the output you should have a link for creating a merge request. If you see this link, open it and skip next step.

    Step #5 - Creating a merge request manually

    @@ -85,8 +85,8 @@ For the sake of safety, do not continue without clean repository. Then with comm git checkout BRANCH switch to your default branch BRANCH.

    If you do not know which branch is your default, try git branch that outputs all branches in your repository. Default branch is typically master, but can be main or trunk.

    -
    aisa$ git status
    # Check if repository is clean

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

    aisa$ git checkout master
    +
    aisa$ git status
    # Check if repository is clean

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

    aisa$ git checkout master

    -

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

    +

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

    \ No newline at end of file diff --git a/c/pexam/cams/index.html b/c/pexam/cams/index.html index 4365cab..5828ddb 100644 --- a/c/pexam/cams/index.html +++ b/c/pexam/cams/index.html @@ -16,8 +16,8 @@ - - + +

    Watching Cams

    @@ -77,7 +77,7 @@ reading. Readings are separated by the commas, which may, but don't have to accompanied by whitespace around.

    Examples

    Few examples of the data from the cameras follow

    -
    10: ABC-12-34 1664608712, 289: XYZ-98-76         1665416417,
    25: ABC-12-34 1633078256 , 42: TryToCatchMe 1671602419,
    11: EL9-987 1679541338 ,2 : Foo-666 1683170082,42: YourMum 1683170082,
    42: TryToCatchMe 1671602419 , 1234: TryToCatchMe 1671602419,
    19: ABC-12-34 1664659649, 69:YouShould-not-pLaCe-4ny-expectations%on^the(input 1680307994,
    9 : 9B9-161 1665416417 , 10: 1a1-999 1671602419,1:lmao 1633078256,
    16: ABC-12-34 1664609012
    +
    10: ABC-12-34 1664608712, 289: XYZ-98-76         1665416417,
    25: ABC-12-34 1633078256 , 42: TryToCatchMe 1671602419,
    11: EL9-987 1679541338 ,2 : Foo-666 1683170082,42: YourMum 1683170082,
    42: TryToCatchMe 1671602419 , 1234: TryToCatchMe 1671602419,
    19: ABC-12-34 1664659649, 69:YouShould-not-pLaCe-4ny-expectations%on^the(input 1680307994,
    9 : 9B9-161 1665416417 , 10: 1a1-999 1671602419,1:lmao 1633078256,
    16: ABC-12-34 1664609012

    Format of the output

    info

    All the examples consider using data from the example of the input.

    You are expected to print out the dates and cameras that has captured the @@ -85,7 +85,7 @@ license plate for each of them (in a sorted fashion).

    If there are multiple scans present and the timespan (i.e. time difference between the scans is bigger than 60 minutes, you should separate them by a newline). For example:

    -
    *** ABC-12-34 ***
    25: Fri Oct 1 10:50:56 2021

    10: Sat Oct 1 09:18:32 2022
    16: Sat Oct 1 09:23:32 2022

    19: Sat Oct 1 23:27:29 2022
    +
    *** ABC-12-34 ***
    25: Fri Oct 1 10:50:56 2021

    10: Sat Oct 1 09:18:32 2022
    16: Sat Oct 1 09:23:32 2022

    19: Sat Oct 1 23:27:29 2022
    tip

    Since you are given the timestamp in a time_t compatible type on UN*X, you can safely use ctime(3) for printing the timestamp as a human readable time when outputting the date and time.

    diff --git a/c/pexam/garbage_collect/index.html b/c/pexam/garbage_collect/index.html index 0e37848..3fb4cbd 100644 --- a/c/pexam/garbage_collect/index.html +++ b/c/pexam/garbage_collect/index.html @@ -16,8 +16,8 @@ - - + +

    Garbage Collection

    @@ -65,9 +65,9 @@ respective sizes. If there is a directory in the current working it has di instead of the size.

    -
    $ ls
    dir a
    14848514 b.txt
    8504156 c.dat
    dir d
    $ cd a
    $ cd .
    $ cd .
    $ cd .
    $ ls
    dir e
    29116 f
    2557 g
    62596 h.lst
    $ cd e
    $ ls
    584 i
    $ cd ..
    $ cd ..
    $ cd d
    $ ls
    4060174 j
    8033020 d.log
    5626152 d.ext
    7214296 k
    +
    $ ls
    dir a
    14848514 b.txt
    8504156 c.dat
    dir d
    $ cd a
    $ cd .
    $ cd .
    $ cd .
    $ ls
    dir e
    29116 f
    2557 g
    62596 h.lst
    $ cd e
    $ ls
    584 i
    $ cd ..
    $ cd ..
    $ cd d
    $ ls
    4060174 j
    8033020 d.log
    5626152 d.ext
    7214296 k

    For this input, you will get following file system:

    -
    - / (dir, size=48381165)
    - a (dir, size=94853)
    - e (dir, size=584)
    - i (file, size=584)
    - f (file, size=29116)
    - g (file, size=2557)
    - h.lst (file, size=62596)
    - b.txt (file, size=14848514)
    - c.dat (file, size=8504156)
    - d (dir, size=24933642)
    - j (file, size=4060174)
    - d.log (file, size=8033020)
    - d.ext (file, size=5626152)
    - k (file, size=7214296)
    +
    - / (dir, size=48381165)
    - a (dir, size=94853)
    - e (dir, size=584)
    - i (file, size=584)
    - f (file, size=29116)
    - g (file, size=2557)
    - h.lst (file, size=62596)
    - b.txt (file, size=14848514)
    - c.dat (file, size=8504156)
    - d (dir, size=24933642)
    - j (file, size=4060174)
    - d.log (file, size=8033020)
    - d.ext (file, size=5626152)
    - k (file, size=7214296)

    Format of the output

    Your program should support 2 switches:

      diff --git a/contributions/index.html b/contributions/index.html index 6d63ddc..ba5eebb 100644 --- a/contributions/index.html +++ b/contributions/index.html @@ -14,8 +14,8 @@ - - + +

      Contributions

      Many of my contributions to open-source projects.

      tmt

      Description

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

      Contribution

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

      Fedora Infrastructure Ansible

      Description

      Collection of Ansible playbooks that powers the Fedora Infrastructure.

      Contribution

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

      Bodhi

      Description

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

      Contribution

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

      Gluetool Modules Collection

      Description

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

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

      Pagure

      Description

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

      Contribution

      I have added an API endpoint for reopening pull requests.

      Copr

      Description

      RPM build system - upstream for Copr.

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

      python-gitlab

      Description

      A python wrapper for the GitLab API.

      Contribution

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

      PatternFly React

      Description

      A set of React components for the PatternFly project.

      Contribution

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

      Fira Code

      Description

      Free monospaced font with programming ligatures.

      Contribution

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

      nixpkgs

      Description

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

      Contribution

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

      Darcula

      Description

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

      Contribution

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

      Packit

      Description

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

      Contribution

      Have a look at my pull requests.

      Snitch

      Description

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

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

      Karel the Robot

      Description

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

      This project is used for educational purposes at TUKE.

      Contribution

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

      diff --git a/cpp/category/exceptions-and-raii/index.html b/cpp/category/exceptions-and-raii/index.html index 42a8c22..018e553 100644 --- a/cpp/category/exceptions-and-raii/index.html +++ b/cpp/category/exceptions-and-raii/index.html @@ -16,8 +16,8 @@ - - + +

      Exceptions and RAII

      Materials related to the exceptions or RAII in C++. diff --git a/cpp/environment/index.html b/cpp/environment/index.html index b051be9..7f48d71 100644 --- a/cpp/environment/index.html +++ b/cpp/environment/index.html @@ -16,8 +16,8 @@ - - + +

      Environment

      Required tools per OS

      @@ -45,7 +45,7 @@ clang itself or in separate package, e.g. clang-tools-extra)
    • valgrind - in case you manage to create memory errors in your code

    In case of Fedora it is following set of packages:

    -
    sudo dnf install -y clang clang-tools-extra valgrind gcc make
    # If you decide to use google test: add `gtest` or `llvm-googletest` for clang
    +
    sudo dnf install -y clang clang-tools-extra valgrind gcc make
    # If you decide to use google test: add `gtest` or `llvm-googletest` for clang

    macOS

    In case of macOS you should be able to find all of the packages in brew.sh, except valgrind, not sure if you can solve with podman/docker.

    @@ -53,7 +53,7 @@ clang itself or in separate package, e.g. clang-tools-extra)

    nix(OS)

    In case you run nixOS or linux distribution with nixpkgs or you use nixpkgs as a replacement for homebrew on macOS. You should be fine with the following config:

    -
    with import <nixpkgs> {};
    stdenv.mkDerivation {
    name = "cppenv";
    buildInputs = [
    clang-tools

    gnumake

    gmock # used for google test
    valgrind # not sure about macOS though
    ];
    }
    +
    with import <nixpkgs> {};
    stdenv.mkDerivation {
    name = "cppenv";
    buildInputs = [
    clang-tools

    gnumake

    gmock # used for google test
    valgrind # not sure about macOS though
    ];
    }

    IDEs

    Choice of the IDE is mostly up to you, you do not need to use IDE at all ;)

    I would probably recommend VSCode + appropriate extension or CLion if you are used @@ -110,7 +110,7 @@ following.

    It is quite popular, only one header-file, also might be easier to set up.

    Might feel slow to compile, this can be addressed by having one object file with precompiled main for tests, e.g.

    -
    /* File: catch_main.cpp
    * Compile it with: g++ $(CXXFLAGS) -c catch_main.cpp
    *
    * Once you have source file with tests, e.g. test_something.cpp, compile it in
    * a similar fashion: g++ $(CXXFLAGS) -c test_something.cpp $(LDLIBS)
    *
    * And link them together:
    * g++ catch_main.o test_something.o -o test_something
    *
    * Now you can run ./test_something and if you change it, you do not need to compile
    * the main again.
    */
    #define CATCH_CONFIG_MAIN
    #include "catch.hpp"
    +
    /* File: catch_main.cpp
    * Compile it with: g++ $(CXXFLAGS) -c catch_main.cpp
    *
    * Once you have source file with tests, e.g. test_something.cpp, compile it in
    * a similar fashion: g++ $(CXXFLAGS) -c test_something.cpp $(LDLIBS)
    *
    * And link them together:
    * g++ catch_main.o test_something.o -o test_something
    *
    * Now you can run ./test_something and if you change it, you do not need to compile
    * the main again.
    */
    #define CATCH_CONFIG_MAIN
    #include "catch.hpp"

    Google Test

    It is faster compared to catch2, even if you do not precompile the main. Might be more complicated to set up, since there are multiple files (it is not one header diff --git a/cpp/exceptions-and-raii/placeholders/index.html b/cpp/exceptions-and-raii/placeholders/index.html index 5e2b813..1de41ad 100644 --- a/cpp/exceptions-and-raii/placeholders/index.html +++ b/cpp/exceptions-and-raii/placeholders/index.html @@ -16,8 +16,8 @@ - - + +

    Placeholders

    Here we will try to implement some placeholders that you can find in other @@ -42,15 +42,15 @@ ways how to implement them:

    I will choose raising an exception, since the closest equivalent of panic in C++ would be asserts that are (by default) disabled in the release builds.

    However I am too lazy to do:

    -
    throw todo();
    // or
    throw todo("optional note");
    +
    throw todo();
    // or
    throw todo("optional note");

    Therefore we will implement exceptions and also wrap them in functions, so that we can do:

    -
    todo();
    // or
    todo("optional note");
    +
    todo();
    // or
    todo("optional note");
    tip

    Wrapping them in a function (or macro) will allow us to do a little magic trick.

    Implementation

    We're going to utilize the exceptions, so we'll need to include the exception header and we will start with a simple _todo exception class.

    -
    #include <exception>
    #include <string>

    class _todo : public std::exception {
    std::string cause;

    public:
    _todo() : cause("not yet implemented") {}
    _todo(std::string&& excuse) : cause("not yet implemented: " + excuse) {}
    virtual const char* what() const throw() { return cause.c_str(); }
    };
    +
    #include <exception>
    #include <string>

    class _todo : public std::exception {
    std::string cause;

    public:
    _todo() : cause("not yet implemented") {}
    _todo(std::string&& excuse) : cause("not yet implemented: " + excuse) {}
    virtual const char* what() const throw() { return cause.c_str(); }
    };

    In this case we have 2 constructors:

    1. default constructor without any parameters that will return just @@ -59,13 +59,13 @@ header and we will start with a simple _todo exception class.

      not yet implemented: ‹excuse›

    If we were to use it now, we would need to do something like:

    -
    #include "placeholders.hpp"

    int main() {
    throw _todo();
    return 0;
    }
    +
    #include "placeholders.hpp"

    int main() {
    throw _todo();
    return 0;
    }

    Wrapping in a function

    I am a lazy person, so we will wrap the exception in a function that will throw it:

    -
    void todo() {
    throw _todo();
    }
    +
    void todo() {
    throw _todo();
    }

    This can be used like:

    -
    #include "placeholders.hpp"

    int main() {
    todo();
    return 0;
    }
    +
    #include "placeholders.hpp"

    int main() {
    todo();
    return 0;
    }

    Magic trick

    At the beginning I've mentioned that by wrapping the exceptions in a helper functions that will throw them, we can do a nice magic trick 😄 This trick @@ -73,7 +73,7 @@ will consist of formatted string and for that we will use std::format that is available since C++20.

    We just need to add one more overload for our todo():

    -
    #include <format>

    template< class... Args >
    void todo(std::format_string<Args...> fmt, Args&&... args) {
    throw _todo(std::format(fmt, args...));
    }
    +
    #include <format>

    template< class... Args >
    void todo(std::format_string<Args...> fmt, Args&&... args) {
    throw _todo(std::format(fmt, args...));
    }

    Finishing off with 2 more exceptions

    Now we can repeat the same process for the other two exceptions I've mentioned

      @@ -81,7 +81,7 @@ available since C++20.

    • unreachable.

    In the end we should end up with something like this:

    -
    #include <exception>
    #include <format>
    #include <string>

    class _todo : public std::exception {
    std::string cause;

    public:
    _todo() : cause("not yet implemented") {}
    _todo(std::string&& excuse) : cause("not yet implemented: " + excuse) {}
    virtual const char* what() const throw() { return cause.c_str(); }
    };

    void todo() { throw _todo(); }

    template <class... Args>
    void todo(std::format_string<Args...> fmt, Args&&... args) {
    throw _todo(std::format(fmt, args...));
    }

    class _unimplemented : public std::exception {
    std::string cause;

    public:
    _unimplemented() : cause("not implemented") {}
    _unimplemented(std::string&& excuse)
    : cause("not implemented: " + excuse) {}
    virtual const char* what() const throw() { return cause.c_str(); }
    };

    void unimplemented() { throw _unimplemented(); }

    template <class... Args>
    void unimplemented(std::format_string<Args...> fmt, Args&&... args) {
    throw _unimplemented(std::format(fmt, args...));
    }

    class _unreachable : public std::exception {
    std::string cause;

    public:
    _unreachable() : cause("entered unreachable code") {}
    _unreachable(std::string&& excuse)
    : cause("entered unreachable code: " + excuse) {}
    virtual const char* what() const throw() { return cause.c_str(); }
    };

    void unreachable() { throw _unreachable(); }

    template <class... Args>
    void unreachable(std::format_string<Args...> fmt, Args&&... args) {
    throw _unreachable(std::format(fmt, args...));
    }
    +
    #include <exception>
    #include <format>
    #include <string>

    class _todo : public std::exception {
    std::string cause;

    public:
    _todo() : cause("not yet implemented") {}
    _todo(std::string&& excuse) : cause("not yet implemented: " + excuse) {}
    virtual const char* what() const throw() { return cause.c_str(); }
    };

    void todo() { throw _todo(); }

    template <class... Args>
    void todo(std::format_string<Args...> fmt, Args&&... args) {
    throw _todo(std::format(fmt, args...));
    }

    class _unimplemented : public std::exception {
    std::string cause;

    public:
    _unimplemented() : cause("not implemented") {}
    _unimplemented(std::string&& excuse)
    : cause("not implemented: " + excuse) {}
    virtual const char* what() const throw() { return cause.c_str(); }
    };

    void unimplemented() { throw _unimplemented(); }

    template <class... Args>
    void unimplemented(std::format_string<Args...> fmt, Args&&... args) {
    throw _unimplemented(std::format(fmt, args...));
    }

    class _unreachable : public std::exception {
    std::string cause;

    public:
    _unreachable() : cause("entered unreachable code") {}
    _unreachable(std::string&& excuse)
    : cause("entered unreachable code: " + excuse) {}
    virtual const char* what() const throw() { return cause.c_str(); }
    };

    void unreachable() { throw _unreachable(); }

    template <class... Args>
    void unreachable(std::format_string<Args...> fmt, Args&&... args) {
    throw _unreachable(std::format(fmt, args...));
    }
    info

    Final source code: placeholders.hpp

    Post-mortem

    One of the things, I've forgotten about, is the fact that static analysis of @@ -89,6 +89,6 @@ your code has no way to know those helper functions we've created as shortc don't return and just throw the exception right away. Therefore we need to mark them with [[noreturn]] to let the static analysis know that we never return from such functions. For example:

    -
    [[noreturn]] void unreachable() { throw _unreachable(); }

    template <class... Args>
    [[noreturn]] void unreachable(std::format_string<Args...> fmt, Args&&... args) {
    throw _unreachable(std::format(fmt, args...));
    }
    +
    [[noreturn]] void unreachable() { throw _unreachable(); }

    template <class... Args>
    [[noreturn]] void unreachable(std::format_string<Args...> fmt, Args&&... args) {
    throw _unreachable(std::format(fmt, args...));
    }
    \ No newline at end of file diff --git a/cpp/index.html b/cpp/index.html index 02f843e..8df880c 100644 --- a/cpp/index.html +++ b/cpp/index.html @@ -14,10 +14,10 @@ - - + + - + \ No newline at end of file diff --git a/files/algorithms/graphs/iterative-and-iterators.tar.bz2 b/files/algorithms/graphs/iterative-and-iterators.tar.bz2 index 93d70a644620c57a719c28a81f2029241c232888..02e2b6875af57670a566d3f8a1156894d625a8de 100644 GIT binary patch delta 1918 zcmV-^2Z8vG4~`EFLRx4!F+o`-Q&}uiWRVRgf7r4x0M@h$1E2r^BUL|C000000001J z000003{ya+nh~`cPe!H@jZ70G2yFmBWCH*I;K(#+116Y;nhb*w!UllRiHOhu0F?D4 z$fivrL)01vs0{#U4H^NE28}dmXa+bk4H^K+rXi+-AjB|%pfqA)Gyni1P(YEPJv17V ze`LyHVHy}rB*vy8lhiV4lT8gY{-S>0bM{0t=iSo-0@$HSF-DmP3EJt#nDut;+om)U z!eW<#@ZpwSSllWJnDa4Mtces#B>)(ZP(RVh9^nZI85R;jL4jZ-jnhRw7gcE?b0WzS zFf1u7#8H7|D2$B3ECj(aG!iKas&fsRe-#R-hHDopuoqkuXiF%=I6@RG8KQVX(S-%x z5&)^RNC*i~5j&tiZ;6Os?I}-ae+<(@Cnv*X`hJ({rn76WRAW6dNx8$R_1Tua3MA)l zeecI{1jYx-FyTqJIZ+e@4WV(MW7B9Lk|@H2qs+{S#Ss#m=(f&l6TvG~G|stFe}+W4 zNAMdoFA5NpC^q7)O?&3EgBZ~5U{a(kP=!n^)S*n%U}n<+#}0_4VPBMLl&qUOCME5l zaZ?-sxT#f7GG0p|Ciq z$E>acVXroF7mCndMrM0JI*xFyak+YUBPteoaKJIWG{7+5x>dU8i&vy>_(bU=8hGM7 z>FD$H3e_MhaWMEg4yabY#^9I<0tpAv=o2^U_3je)z)XF1p(2$M874aM;GaH*b`v7d z!q`{nsFg2{B5D%W#7bm_e`0Bcvh2`J8K9OE7YpwpO1KF~rgx<+N>-v?34oGJ$D_k{ znC&{?b;RI0_da_kL?3X@NmjJ2JK9h}N5c;h7TjH0tZ-wf^=#E}{cEUR=WsS~grQ1W zX?hu0p?NU2D0#vl??o`DzvVR-HemPiA6)}kJN~kXc;gF~uO2x#e;F61u!f^uO1ZZOYe^P5O4LGndFccujF%wb_>&ectrI|u{s`!R}UoB%gN0)cXd%>Vl z!U6ZwW8^!?W*LMv7!R~ss5BE;C*Yp($zd`8`}M6%QI7!!gkWf(YgPgIhZ+W>^hB~S zDjU}bl|#%G1M3rzHjVcqte^xK^RzP;w?U``7)S3!*1prNe*(z@50v|aZf6NwP^T(%sJDpTVIqn+$l59$`Y4S+nKpPiT0RJMc-L_V z9JbJYFTgbc)0Z%wVL7r^5QGTY$J_-6NgV&Z_wF&^ZH?IC)AUQZOKe z6Z!#B{J^qxfmp%}$RZyHYy*kct{z?y?U@b3hw|YaYjKYW=@GOh3c&f1p zDg{!EpyD=50q52Qn3Bwaht?Q?VhMhME*?#)@EisJ8VO;h@ia`XR45Q*UNNQ9*R)Q) z5crtnSM)`wx&lzxdF*p<@-T#fBElg+@fn4M@&Sh+=up_6BeFajO#=M0!gzg#C%B;e zXUvXtf1(Ew>`pCRsvGs*_FNNEo52(&OjPor65k+vWDk&tF^Lu>R1T)8#EnM)<|sOI zNJn1>1LY(lS-?99=I^7Z=SQ{`hhSKCc#F6QX6PjVq5-F7wroD@V}z;wJrkIrjWgZ~#HI78h> zXukK4N#~RQey3mM>8MQ;Y4Duem~Lk0qo%0~c_> delta 1918 zcmV-^2Z8vG4~`EFLRx4!F+o`-Q(2^m@R1ECf7Wb_05ni20000E41-31GHHlupvW-{ zAZQI3n2i7c4K*|hX`q=IG-%KbGzNeG0002U0N}_pXagpghMEk65W)t4(TRxA005Nr zB+;s5$~{9(8U}y>0MWHH00xaTXlMZ7$TVmJCYXkr41*BD27u9th|mB4i9rHM=ub@s zf1tvdGGu6Am{S^V9gW27K|t^ z@Q?*fqCh}OfQj7!`#dZ{|6xjdL-}T!896=+C(-mjO*NZbxYjgNB%7QXpG}!-&7w|* z=i3Z-5KLJ3#kdk}&XORI2ucE?xgYO95J^IgkeB)@luO|82*yfE#hq;UT|mX5e@jf3 z8j~L~E{Q6VBP5Y_YEa9N%5UQu9jppeg^CcVg_@KpnrsZ(U^wC1idGf%jZ&49XJEv= zv<@0$fEP%13R>1HbgE8)l?qb499Er*3RO)DvA zOpNH|wT5v)Y_+dZASf18ES_KyGFc&_8urG+;Rvn%Cmmmb)B}T-j&(JKe`B?&Luo@` zaMO!fTn58lT;wkmpuT*}_JDMp!CK>T^!KAG7I`qhF}*avFza0^-E+mO&NqAlbCHca zQ66OS_JwGW6|k50`$t48U*~X41c3yD=RG2Po`E$#O}7bgFvLlgRH8K!86~cIu|8}G zI4?wgdN#eL2v-C(37ne;1~(hNE3dzUYTo zov^3Q#`41jJa3|{NZOZRa3N|2Bm)vjS`xa?mum10T)}9*Pl3HOy`6PcRZ{$orpJKL zAqK&CkZ%s!XmGYHmn1Gxy=Zo5)WgT7#E4e7=QeE2t_~2DD#&`zYPGKr#WP`?Nw4uR1;{_ zI`w*0;lhMMvJJ6mgn5OzoF(w7PCV*Sa1p??iYVhFXsCCnqBR0!-}H3aKJ+?#OSps% zOK3kA-Wq`C%al(joVhCqLJPn=LvW9J1R)|pj3gn(aqf!(K{t%Tp}Ny9$nTAaE-3Co z;^cLaJf%{de=2?hwc}O}<9A>;JfUqtY#Fk_XKA^+{5KH#NxOn!fzHgWSXeEZ5#L+UjP@qALc!rlxR?#}R z1L9+mU(FVx=m|q%=CRAx<6#K`MTA0u;WG;h;{y&c(4nzBCt!E>ng#hMfbe?^PRfJv zpDH=he~26>u{d>hsCBEo?6@YSH-ackn5pDKCA{JBkUZo;j7YI6pmeoP6lypJDM8bg zLOS>N-ytCq&H>j?FMSAR2l^um;4)8@mI@6yy$Vyp{+; zg+fuOe&JzYTSzBUX2b3_I0~d54L5?}*72jLe<~SKgOHoI5_`$dQgn~7FKItLdWfBA zqHPb9>#wkcFU6D!ZLJ75IJB_X2@ueUaLvGyT**81u#FUf#IFz$BpZQIs;vboJtqKA zDusH#2KvD;7nouu`J!Ka9<4=oFb$*<4CXF@h+^zX45$<*)(8FKADGsy2mdZYa0j@L zXnprjLFSY8{eK@tJCG@&Z9Ws1a}CVg_WA0Nw~mFWP_IgkfO5En*ZNVy2WVYMMyXY* zKo3g*qGFuF^F@b diff --git a/files/algorithms/graphs/iterative-and-iterators.tar.gz b/files/algorithms/graphs/iterative-and-iterators.tar.gz index f09d7c43c27a7b740860cdc05938f3dbfb682e2e..b47661c79bdc37ee1a754661eb87b6a6a3f1d349 100644 GIT binary patch literal 1960 zcmV;Z2UqwXiwFP!000001MM2ia@#i0XU*gvP)!fiM4|PtteIF=CbjIeGkLX^okJ!E zT7oRr6sdrqY$c;F>!F|2U+6ACN+bnRoJw)*2791PVzF548(7<%GKS<|s^4*V(e{@mLRY5<1^2l!iWx9Z}(-foLugl7G4uYS;KwcE9WMicO0u-@1s zwJp~z1cA>jM#vruT$i$JyrDO^$s2#9(0LE~r2|gRhd0ONH}-&ezBl6L+ta=YpUT}Q zr6(mq5N%2spTA;WFzw3kJja1RYJ0A4zM>!wdvH`Lxe%oNsWqTP76s(12-O3}@_hm}(&=}}?U*u3`s6ur zJ?=ut4v`S1%$`}Cl2NlJ^v;+p+CX zVo1yrF92KZlA22BxM%G?5(zviKAhn!x5-=2)f&&CJEm-dz>xE(zYO0c1HECYO%nd>6d6uW+I4t!oW-Q-= zPvj}7XHN^QKuiiU_J)vD?o8nU2n&T@tbLLj3sxKZ#jyrAM_V~i7|meQ;QZv0#8uI` zsFKUB5esDE0~tBiwO=I{B!Jh*{4Xshpp}%-V$8o##(V@+y`W|G*&G%YBn%+x1zeaB z4pvmE4!4El>Fq1f;vD9M5l9zH{r5cxBLSFQHz5)u8n5E!Yw^4wY4l%&mI0AcNkEQ@ z>8rr8PDd!1L@`%MDRh(|=_r!YqO{o2StqalgL4%GjLFtD;D-9I(Q3BW&i@BBUH{z& z{PWk}@e=T;v~58c8cocr!{8%}AfGd!-z6tds&IOGXHBLK6+>&~OjN~S)e@%I*WjKJ zi8XwLvR|%}@@IT-e9ZB|@G-;3Ek5q>@dY12IT>9P2|lXJaP`Cv)^ct}^)<_>yJR|k zIUHUJbafS#3i-=9n8FRY-&r{|Cxs;B;TJ)=ErP^1Acc}IfONM3X)d*ykHm^B$E3dV zk!D3ia9c!}cSR_LhM14^rHGt@r3h3BGW$#sy5`KYhvbcAyM{FGkDrLeuGdU9?hh*e zRk+V^`>X z@HzP!XUT+oKY*H-(cw!Tx!NT1BotK%t8E|PJ|qtR8vh4QSo z8WvopPtc1T{;oXFA-`JwH{~zPp)ocg!*IxzzJga(_8nP{pL;I-?G)Tb#$7a-#O;hi z-MilquDE0&oru+&3h}QX(VkAGd@hVBo6sXlh(8$Q<^SIO^nVT-wdPv?r`gi^|2|;b z<9=_4{U5xb8hz0yIRHh#c zz+imHBFLrWfzlgglL{sE(`rJj0hMJslAbqB*C|WMMeh7@#nV!Fu}=yKio=P@3JC@C zOqhF&<*@%%)bvqYF6>aU0Zgou%4j#mZDK`XxwqJ-V%CwAsIZb14W+59hAWkwd+WWn zsuZJ_kFAlly12?}WrY}7%`Bu7yVz1viN>>NJeWq7hW`W);QznY|NpPiYSi0%q<$aF z{owWg1L*%M^xtmO>l^gHE9SKRzxVyWLjQ-2c58$Fcg396|M$NCQO5s9bA$eO#oQ0B ue+?QmXwaZRg9Z&6G-%MEL4yVj8Z>Coph1HM4H`83f8bvqCoQ4?Pyhh2{m#?? literal 1943 zcmV;I2Wa>oiwFP!000001MON%bJ|D{_L-{uhgoV5qC#XI2C8CADlxWqtMb}4b`Gf= z6c}u+u|!5A3`z0J_OL%`|H5|9Na(>xr~+}E&3p%8G(A22n(m&#HmA(u_KZHUoY50o zd~=z%f5oinwPy~!DRckY+YU8A```dS>z!6ze6M#p;uF!VxA*D?tyZg3uQh9}JshkZ z?2+1*>lT9Vaf=bM$9%`3ESqlR4sY_te^7Maf`93dlk?HdQTdfUWUl9qx%v8JV8W|% z?@{Sdi4Y{4QpOi&%=M=|d<8Gx_%ZRgWrspLT3_NLa564@t^FCu$W$G;`O#AU$? z#Jg*Vsw#nCT2#r4i8Z_tL(7u*7)~tDBO=negC4oNri_vSc}g6YJCOQgjHb+X9Sj(7VK#Q8~<*+qZ?17F%=&)x?}0p`)u5w;XC*B3i@$II)LG z@h(I0A~g_D`^Zrwd?e>`jor+(N96fvgq-Ny7!bdbVis~Sfy(e>N(+~uI&!3{uu!GQ z(kH+J7p{V1X6e=KF)`#K1GYG${L-5E6c=-SPG+#R#Na7&Z!aq8xhnz1u#j?=l7E>a z-$&P-kl!rto65&1_n8wH^VoH`Wjmfi){3x+XH9}#)IU96?IFRfV*cqn>9!+dH%YxObM_Q; zXPygf$vXzc42~<*__h2+GFTd;r{qgqB(raOLl^$0qvt%_e#1!d22E1a3vEM-poVXY4pfB#~~FLNuat800S9G&C^+n zU)!D;=GE+69q~g>B4wr+eRa;nBc;&b%{WYNV4*}62BOy%c zVRV^^8wS5}xS}v$K`neu=NuSjd0fO6uv*PI_8A&XAprtI3)XwX`hgjRo2q11O@>#o za6?Ex&+>d6$I9Pg#_F5@fjlPl>}f$1h)I5iZiu9F(>FpPmWq9`_DU+|M~aEd(jvDp z*&8UxW5@q&ye)|FQ!7kHs|8HT^OWvZlt7IXfEGUp@E^@3N{ zMHLR_T~Xn9R*MxQi%Xc7Mxb1*{6BEz)!I=nVG<)8ucGp`cwLY@2G4@XfJ~`mAVUwk(cCQ&Q)>>Hj1CzD2F?4E%W-n{{8fS2aQ^Dt^aFubpLlB*tY-c@38;F4a)6X zx~UrrJHz1Qwnc9!IE81sE%IQVFXGm8bH~QRx(;r!D3@aYCtaFmw_`qe+U8NK@~wMr3{qb zD4SHY)GyJ5SOc0BI+C9|O?TNV%Z1zdeI(P$c(GRs3yOYA6@`RCcqYOG=&dop-)5%fCiqR z8W}Wcq3S(N9;d8-pn9YKcSZuC%E|~vD*+x&+?HFD^?`6DpQMpIL_ZT4M_YTo>j846znvh>$cY4}@}%8hqmwM1S`T z0Y>5gK!U5a$~`LSU7pJc2M5_e*~Ro3QUa+DaF|*>+H{AU{{h^lfg7*)Ke(!P2b@eA{=qN9G{2^6j?0?^nM{j95K=6)FBZ2B%%}{^0 z75?MPBT094%e{fxesjMh#|P}}wSS>V4L8WHFD(kGqcvf(k(L`sfQUT3&eN5JH1&TS zRaI40Th4gw*=uQTj$a$J^g17CVBGnqv3oN4UE2dhnqz~~oKumH9Mg5BaZEJ~-OMpcb8BF@Fb-QxE<-Mjxqqk6-Nd&? zFd89DO`-B(B616O5Q_s8+oZ#PI7VxaA$fyMf8salF2lXYnjDa=iT1vB=BE68yLoUZ z@a8UdXR{k~y~&__vz{2ufjGX3HinrN%dpojjul2ZA3l2xGcqzVv%3FEL^9|7yxeYN zM?}fcGwt8qjKy;=0J==y*?%%+)Jp568bVFml(9F78Z4S@y()ZFiNR*>DvL86?)y<~ z;lxg`x=r}$aJNw~sMl4*>MRSrL0K39Qv*%c6827pXX1P0!#;PX->}|PVYxXUue(&) zzfEncd)452jG=ks5jZw2YUO^3WWP+WdA#a~K#vu<2QtrU!O!Yb?|&!oz-$G?g@c*b z#8fN?Dv?_5x;B*Dv0Al{7$5Kg4hq%y=*fa4KAEIUN*}FfEY~8m;7b`%|OX*_NO>15vTzBgz zeZx^KiA%Z*ROFjNntyC-4eGHk_F~@ypn#>4408MvV1v=;JZDVu*HOVDqhL$s;f>Dj z`(q8qJwlh-C8dfuRE03W{*&-!fSc#xu~<-5{5e zVUXtz5!`uvy?nJz^u((l+XqYl9VD{@keqrc-_}T#>&M(oQ-8(>vBhx4y^!)|$e9L| zmZlbxy032rZ77Cic010y4^WxzBKQ_lqn45f?QD1{<0l`xWtzuS;18Jzl|222pJf0wW4 zkD^rrL4kp|cYk(XFKqu%)su?3N)r6W8YaPu2O-hMzAvucHKZLU*JEGmkfp1EfY$v+ zoQ4fmhS=qh=sR)KJx67(JlNX9rUN(|hZeBps_7i(l0!$o9nUPFU)Yg4$A5n^6=W5FP6WAHA z4~^|~4sdXP06ngj#I!FO+0q!8&HT@e4DJCZFc|7KB_bNVr=#9{O{qp?$pIv&QCA>P zG8QDy6w$mdXMRo$<4qF4S`a|T7t42CZld|Qj(?_w$T|m?f*^?w&A9hxDb7(j?{s)Q zMW@7bd)vfz9+P|wFuUZ3rE+x=5a1l0GhmTKLV{2~SU4tmhXMVHiL^@f25M{eG-=8e zC`^#1fFSr!;J+Xd384iwNn+>p9~y`2LT+12qbbmV9*%_EJ!_GE@8N;u$9H9 zUVjGm`CMfZYV{VH4TeO4jo@oEt1&H9C0L*}frBbw=y==VQ3;!;{{G}+?Ad9<&L`b4 z;~{i4Y41oZ1FVLypjhBlkV64Ic6(JziKjsX#LbVpMDQ>OzC-zT02$oOGh|@~J@i-E z5{bNpF&&{hU!0`iwtk()(H1^<1q3+6;(u7ZxT>UOf}(GDumF%^e=x`nV-W2t4hkGR zIVn&9ZT+R2SJ+v!@ElW$Cau)&Aik~#l|$UWAz)1FK${!^c}2lJp|hZ*A{Pi&QsS{< z@*gQh`_j)OiOr((rYS-a((@e5l0-6wEovkSC0@(4LMJdgMK%zKVr>C*IKl?7&VM&R zUo$EY+@X7reo};j$w>tcdN!+$_ToH2 zFjUm}tY#+xdIQoF=%zz#Ml$62zAFWY5X<8-$Efqb96t!hsekXhaR^ufOR%M5++eNwEy9Bqlun}rCIf_84`Nz4 zE=B;xlO+zULKa)WJIM3qiEiGx49a{0pHNpwqz~u#dfm&`XR~EjeLfi^^Dx_@x_}!~ zXg(YMekOLSr6cuZYP*I9Fu;6LL^VOkX!72nnTmM5(e+w`Ub=fV`iw{Mp$w;{(rJG0`CDigP6XCBLVDVkuqNDv|#h7F1c zKI3o!(ioe}0*^UOE@zZ|q7~Nd3x~6%s9oKa@1}rj%oqeh#Uv{XZwjszO`XCG*{h^PHTsQ4ZAO{npvgEQMb8m9uUo%f5LN%v5+;szx3lCY2<0$p( zD{}CfdmzB@@#%EhBl*G;NMdQlcr^xa=!0SPg2zRea$*?-Hv!eQmw&iz5;$@|<~iR3 z0}&rS7zZbsNh0Fe^8|cJ0z1&U!#wZw9NIz_b71Nh1|A^lJ5=FSZVFn|RVYwduoftZ zVj|h>9|Rxd#5=kHa!iUYJGw;l9cIiKuB=40V7KDXXoI7`0L~cC5NH-CfbOq4S z%M*b@WXTc`12NEf?tfkLbNHDNw%i9q$fwF0{x@l88%jwNiC`g-U?$>_ciJ8*5F%ZTf0t^U`5!4-T-Iyjs1U?%?a7b!-o_HgvWiN-K8yGzNKn%)( z4g@G4&It{n%ur#{SpyNzwUA+8UBuuc4e8kYN%}_X-kOS>JEq~06_`pqtHzw8cnEqCejC}Wc33k z8k!9NX!3vnaL^3^27u5S0004|jWhv}007aZL4=x;Q`HTW28>3AfDNQ*4Kx4%00E!? z0DlOSO;tZ+NwqyAWT)vz>OE2FW{IZsp_9^RG6sx*0gw+9SxM*i=ApS#n{>j%(r8;(Pd zz8G6Tb|aV!ipY!w(vTZNYBT|B7)}4xnt%UpE3@QLR2E3979gUE8UfM|Ci3WsjOp6a z{6UB4B8<8tRFAqieFmN!I-A!=RcnStSw+-i(LyWh!D7{i%$M>eA9kV1VUi-uk$(~f zjU(Y4qz0c*#Zf)u08zMr5Fo1dx{u#inRx%UMF&skz&QH9$kiZThp@0_Jo|2jqwXE0 zHk9*gc-?nHr=WN9;*lX7HTW*e`Dok@uwLQuPsQAF9eqjKdddslzX(-XJ0H)_(c9Wi zkUS%k#Nc@@W~e{civMBhk)*r2<$vD5?LRT!l1eM{@XDO%x zz|3&$^PPq%r#N?5c0)4_M2QMgnsDfv zh~&aLth8NG^|s6L))_1lC9^&ieS)ZJ$}3VbMzUE^7rmX5BY;s}n35c*oqu5{rUPBX zU@<*6Q5;)&57UShK^#q>@7&?;3Ti;p3{kbPU8guUYMz;5CopAnZ-*Lp)zFNuZOCJ zK|KED6rfCHR83SVwVQ5DB!8$ufPx-r*74j#vFsS$$1>T^ni~y;Drt67&CqpywJ`!P{E7S1UZz?d{ zoKM%?s%+n;w$;7r@H~v6dE*f{HZ5x7eu-4Oc2i-L&k%tgV%$NztAC|n-|H#Hp8N*D zTu4|seQZTSz;bC7uH&U?P0JOlROx}_2&{k^F@})dcMSRfuB!9`#nB{jG6P;)zQoZ? z4_k5C9TjN%rR`|EZe4I}JrC>loaQ|OqbrzA;vO#BPqS<3zSh3#rXV_@O5aSD<(C!p z73ZUFiC;2+d?R4=RTlI}U*?8!*h7j%B4XktwKC7$Cx&tmMa= zu%64|3m5`?JAC!hg4VtUMn_)DfM_01EEE`IEMD0}DG`LJgp^JO+<{Qa=T!(spoSs) zd;SUd(%@_`V1M7hJ>~CY7m|ZrtyXiH7>bdqEG9{XF;#fozsrA~>si)$i-qKK4};hS z!ISP2g;|O3h^G09K(48Ps_G?-Um??A}IQl|tAtgI7`_*_c3`to7gA!ob9Xt;lmy65M@5PvYF^wJ}S*?KDfNtH7*fx|Hx zwX2tR(A)KNlv}p}vGrIvIXZc5_?7Gkk%<*JLLws=#Js^!EKQW6N{~=Bpu}W@%Dsmn zDjbg8%b`?m7%cc0!=&-Ybr%!hG$D{tRFILalu+DaTOxwDm-hV0(w_tT-}QLD7LD|K zX@L@hcz<;}v%82az{Qa;LmQ;;g|w5Rz~1eBsDLjj`<39q=2AZt$C$+zEb168WOD{w zVcK~d!^;OFz7Hd~;!DFA`AuyZQLFC1Z4OsxQ@jpNql#f8e+T39zayGp*s(xTR4A*E zC>aY9XNqZF7qh)4bmGk-z*-3gYWT43P75y|qi5}krGFsd2BBZZ^uvlG6cT~_VBneN90%{zO`=zjW~RSeM&~Fl zP^m#oz(cZqOX0@$VVrMX9PR<3RK<1W!v`V(z(*m%2^^0YGzLLS5*)ky0;vfDs!;D- zWq+iTU?J%)LWYA`dKgWRHJVkJmZ}o0P#VC&kuY=oP4K9M&HaDBy4^-!9M1oMpQ6F* zBJgj`%$ifVJ=&!CN z6L|_^J3@B9IZ456{oTgV7Cxv21Uce!mVYm9bySS7KziyE02~;fP+ki$h;xz+Q8za) zi~tH-XtQei%Ql_^igTiB-A>{Q<-qi)d)Muj2ySfxW#9|SE(z=nr3E1nxI(fQ6^j>< z>Xu&`V(L(>TQ0=gOA#+In|WF#2+}gPqCm1$?7KuFas#weVF-pM&=*6d3@HY2Reyrd zFhI(w1(o9X$c_r6TnDhDs-Fi1UJA zsj2eV%uWLHLs(J4Oha=Za2(RM3DqQwWyIp)s8oRrzC$c}k5mD~4`3BdEEsvEEi6jj zPFP+kR5I8-9YqxA^g@VqiJ;E;?|(W(ECD6hQnBtZR{U1sL5oT!QGycz!Yv1yS~xC7 z0LGIg4y-~JTfsZX^5%(d-nk6Qd;*^!u8~L|SIzBrFIk?=m0k4sWRsbO-4)aT+M7Y} z-}CdC+OCw3(UGd|7#xEE@ktQX2O*==dWL2x=mx5%#IW_8j_@@<0p7TVDSyahzi8-7 zF9Mfg=A7ZoMTn4V<4X>!LX0W3mRwbCAIWbe9@8DhqxAKd zy7!#lR5qUfUo*{^kMD#|VB|Tu7pJH>L!u3b+6x^PVa14K5Znh=+J9c*v`FE_1CZr> z3=BklSYRApNhFJlXP6`6NDq@D7l0??4E(}!;BXpP5^2?pXb4uHBE zIbv`qOqn7=0A@N5Eq}|r+`cA6ZMOl@GAZ^ua+ zfr%SOP%tj`3=`-RK{kgFfI-b76q^bFr3;+K#ZwWmpDv5C4;ZJ{A^uS<5R$}5r}j{F zk|`1FOk4dd%JC-!_JgMG23rjeyd@+~7tL4ja>o_~}D$eZDbR5|dz0VTw_ zN_yzHIyM{v0Xr6{hBQoj%OQARejd0>vEl)fIgY+&;9fEkqn z90*W9m=YU9kWj;2ll15%%BZQ%s~p25FHZbyi4;Dfy7?#Iaqn zv#Tma#RAD8i3r3{zho`@6gNT|3yT(eK*90ewT+sqNH%9@TdD_6`oJyW2a^ueQ5$ zu>XivADE80CB#iL_Q(%CkNb=Jbw%fLS^ICatUEog%X_SK{NdyAY3tSd_l0%%?Rea* zDy%zR#|^uj9olYR_>LS5n?_~F4g&5=v#J+*9q9ibFEOYLn#K}fzsEofpS0u#3qB<3C z6EEuZ(DS+78Q5)?Tg8Q>jGe%dyt{;uwh%5*qB~j!0h*+Hlm(RbY&S5tlwxd`2h#Cu zloojQgyaDc+~$49^Bk|wt_R##o9GBQS|?ytJO>nw^I!t(nO?9Xef|w-iFtVrEzkp7 ztF-oi=qltPZ%H=t9hB{9iz;r2Y&`we$aZ|I%AT-6bhev%=HhK5VqPTMhk8EX*RUm< z48L!v+x5V4IkPORfz?N1bY-R2gp(q%i#CE=+hifqTEbBcqYd^*TMTIv#KLRN2KJaU z+l9mLPFYWcUYB?j3>>!|YCHd<623 z4_3Iz#znol66+rBy<>Z9C}96EfCPiPF0+9Hj(i+|=t#-^P3Cjgp8WS`sHC=V)U_pl zXT*LzA+m-R{KL^)bz&PEhVUnXrFip15qoGh(2k&$c4%;#E$#%noj-FU9ynj-@ziBe7YVfPerWE}IGw4^w0a&z*uDRzL*-BekLNrUz#@^1*r^BlfNg% zw|grFUP-+H?Bg&DrTu135HJLP;|yoSt|8uZJca*}kUIk|n8jFUrKwE%;`y#o@_849 z=vNfWeY1cG*7n48iYrQ1Xm*S+0$?h01*{6+BM}4+(7w=Y(rQABKTPiPfJ>UI=h`rZ zOz)(yNR|`Zo3&jwXuasghS*UDrY#hC1hOO1fv{3yby=C!8qnUv-LrCkd2HzK92(LN z3>3p~JuvjgALnmht6vl%&h$}-o<-p2#;I2V4!YL8NY(WmKadxu;-?Azb)&a@zF&YM~9opWMNoUAOmlf2Y1ei`T6b$Wg7HUre+L}snoMNKkUtBep ztKocy_Zeyh+yQ=ps`}l3durBdImn06rCj!N+0V*;!UP&cODm+`hf@HT?g}vq3ZF+4 z0^OxlZ4wSGCVL=B>Tus@hlgzK{Hao~@(C!|1v?>MYo}@ar?(d2+&0MB(tGC|%DT#AX(TxaOWAO-JMyA%uqbm|dO ziyQ@7GsHr4Vb^Sb;4Psab~M5xi%L)06D`6pV8ea9{~Ow)qPBf?{9$25f@4}5+Nhhz z764gEI1Ia00)R{iq>Szg$Y3KMj^q@4#9vqyW}Y|xym}E&!EVUjnirmFR}*DWBa{4( zx2G?TpS?PM`sPK0?6o=66aLV4TjV2WhrWGx`uF2Et!M9lK75=VIu^w31w+4oclze`0rs}bF^i)6WM&e+%11p@cG8<2d z;Lwt~Db_{sA-HyAXTYpsH*vZOU*a|87~o|C*)T$qb2%E%RZHeF@)FA@5;B<#X{8KQbp6MBcIe6(3QbYb?mYsElpVDF zsY>xAcyJ1^rHWS)@YFntw16rmanppFNa7Qw-mzwU4j}$;tZ=+0-bAiEUVnV|4x+xL z*}kTT-oY4C5z@GaWGu>ErA0OxtTwI`h`PsluLb>oRl7L=!op=562DTAMfzh!t)AGb zvcn?)%NrXEk4>+G;8ZtF@DYzqpH+N|-}4=Sayn{Jrg?*j5hgpqLLOR~h9FYtD3&JZ z4X|?zz`4F8UR1Ugt!wlKgC=q_;v!NL*=w>z*vUBcNZGw`$bGP*%C(RsMT|R9??!+? zpPik5ff*NoPp3=;gJ7Kow%6A;kT95IVwHOk1E2y?#7j1B9tnmp0SSAJd3_8if<85X z$mEkgm8W##Goh3(uEC4+E9jlHOc;HT!79qBW6wmRM1WaRY%yavRlBD1q9)K63gM^r zXr5#ws7)iFV@FD}lWudO5S9-_>yV}gGHzrRx7EYHqe^tQ|t+w5{v{YJMk%N^34jALALOBae zcwALL1>@9BAH)I#^RRhyTTCvIRDvK`z8L4J7Udd{3N++b5e&(^&7<-V8gd|MVzd%} zWh}!0DMr9a7>rw{cHjZb8U0QqEIG%Bb_)gxdF!QML8x=GD8`_Rn={)=!pm*i} zw|Dll@!xi>mdAfzqbz@y6KcSWuAZik|B`IYs8p{Pn>FTz)7r8uzYFnbONy4xBpWfG zqHu$`#cWoe;0W16(HV}v%aCReWv#87Wi5#y zmyW4a;C~7KmF_)ey;Leyu&gi!*3qT1!WbNcpR0^f!&V(rs;sZLj#_DzF}fhPS6WAx zRo5});5NBR=!j4fRC`MSJ;m8|wuV*xN;=3l09|_M_d>s3Yz$2Y`3r}>q?|W@G|{N& zPNwI8m)6KRP7FgVA%^;e6Di@*`n+D8o3wlq&%;zU>pY>;;9w5Cx z&jLWGJt!7uX+A%pdDzpF3-&D8vr5HB8;w>^$UjQIsk4BJdF!QLKrog}67B~V=e3K} z>gK}nMdb>MKG$PDX+ib(kqa4HeSVROJi_AK7&J`9pmElv#>y<6hdF>6m4&&Tx0B=2 zz4wqLTyAqn_{B>a|6TH)d5?5OkPNddl3-W2ll15!T=3Q%s~p25FHZbyyWrVoE+_J8^86 z?Ch#aQL#XBNFo9;6fmI3XjQeZwfUJx*(XVN&j1*JheTVpce5C~NN~=co<6?rf!e*Y z6lFV*w!clEmBDDV_OPW2<;mV2e%B86YxKKza6sQsc5AzTwYA#b{{H?!t-4#?U#r&k zb`Pp+top!o%q<~qnz1!M^gQk_?$;Ha%Vq7q(X!$6ye{vt*71jr$EU4V@81_T;J4#( zv#PM+cpW$Fa&~CDec?NDFl-u?9XklPFU_i6=yjwcJli#E#b~xJl#c7jsaZAV9Vz^# zvF>``w?_ki6wdWR!49QhB&}9Qc!6ZpxXJokO#L1MF?`aJn=BBa-{Da`4%}peVu3*^ zH(4ON^}1T@(0q10*=({K=(fGhhV~_ALFjWP2exFt{PeS$^p~Ih!}!DrWB~mX1FU{! zUU2YW@k}`GzNAm6xLfS&OK#A^X83bsO?ok#{+Oyrj;8KdQT^>ls zvr$^$*%OinL~xt;9nW*TKD!=pUu~iz;AowIRq-59G|qzwuxEO~j`aCApe5$zIkZ3z zY^~CN+M}zGhrA`($ahe-r!A_uA+quGTO-@?ttxxW2GQAW>6weSjfi=XY#-|RfM3Iw zY%=`5p>Ed$$K}kjum)BiiP4pnUK37=#4g$hZf%Q&NNWj4HHjH6g_Wbqfi)SBSzkB;3nV!fWPoD8xc83jv7vzd!vGQt?z+qd4mk2r0HPx$_qUkOU3>E1pP`c4!co_M zmYfm$^@PY8TJR4?bJdA$ZW_X$2$tf_V@2$t*+4sjR@$M#X|}i%>~{Xljd<)R3k&T!;| zyBTs%wv?;YeIrN{dLz4YsgM@!2n@LJy9jIu{UI&5z?f~b7#KBl!-N|CWHzXOS%XVw z6#KV8J3fF&j9gSf`LC?+IGXRuB3GnsyQW?nd|0cGp41m%e?TjG2>#lDe1ZsTg>(Ek zxNzFVYQSJ6Sa1g@_+&^BL!NO80N`qvP9O;&-5mL zPmFK(Rt&t7dIQ+UVHisL&72^AUgcg68+~)z8G*{2H zVG5bvNnw#JC$=|hyKK;U(TfeSqYg}4DDntoN1_8^rNrv8GOIP9y@|VjXXWzP(BC;U zq#YP2hT(c(=#M|n-@aDAC`6p;qYgcbz|W0SuLK-)t$UHG>p6ZPFHFU4^-zNOef2l% zCzq*nuFAhf^}F}ftkrUm52H)D?B}wdmHmVXG>Vp1NWTxK0507XViXiU zk0u1VOR3r-99m5FK$6tqzRwO1+4}iYrC{X~P_PSjLcZ2c)A&zsJ;J$dkh9A>bUd59 zQt|HZE^}q(f4a`UE+L+`A36(k*Zp7h$$lpPvtNbgJpc0*N}T_HdH(vZfBW$9^f;Xb zO4a@vZvi8j{UTmBzxm5={^;f}zwOI!`*iu0-S*x4e(!TG_DnDEyF*C--^Ij#v2%Uk zHSWNF`#ZJl{omg1lbsy@eT@?1zn7=S?_Z_CUs7d)ydk(06Q#M%(2+q3-mP{i7zXIn zBcv8N3bba3h3LY6uGzp_LO<+ighv*Yp0p=ggkivj`*{C1v`0m4`|9|^!iogPv^2C) zH<2v>vXXEZcB=#cnGi@B-4&3*Mm`+LDfo!Luqwe*fvrrqtepO}UgCiIdg2xXdAd^&&p?XZ!W9{gve%Ot~!EOguIALWr zo)p2MC3RD*i{L|W?a0o6S;KDPbQQkDYsxXe%LcMxiUKE8<}9#>3OYn+$PPHG*0VQp z)kb5?C*XNZ&wl1|G@h%L%w^;ymQN&PG8xiJ8K~&`kN51*l`|BYqN3e<1QaPd zX!}!@;z{t}6ktmguO#59c@${@RZQZh2{n<#CrrI#&G;NZ{NY&Pcul;CTzRzd=e%QPf@r67y+$BJ4# zu~lVd*P7#U`Lf}AxnxFccR{n z0D(S#J39k2E&!iSnFFvr9y_aFv91)_+TY~DN)3}FHi_8as17*Yg% zY5BMJ3DPLTJ7wK2fJ879P`XGZ$w*L}MnK1olx8R0=0wT0;!HpSwdLA>oRmSPTWyO~X9t(58ab^%LMqmtMG7(9 zjdcIGtKMHaWN+wHl8&$RkWF^Am0530o^mXlE^+>vfG=2P+Wa~zydcD}JF)y6fmu2}~h(}vev~(uf zi1`$So6Id{v-$)_$R3(DNzdRW2GCW12GB6Xs0UW+Z59=D_HRt@r#)JRG=nH>eZws4 zNd&ocOr-+E|nF=;2`{5WsDlO>X=exW5spUN~?^~1-ZS_ zI=Za7jwuJX$yGu}gp#1zTMFnY&aSg{tm;?NLB0X#(nG%&`t@RCXgbJWIP@id<-DPZ zMn!irJqNtBM$U0!7-9)A)GwS!36C!C0WK9jn9e8-zk}E`V0K&3dlF_oKY9DCKLhmu z>HT>Y07C6Su{cZf`3cR#o}OH=XUU#bDn8n1w0c7RQTk1t1ysyiFZ}|7v1F2PKe#xr zU8Ghw7mhC~S6KA99`i{Hs=tq2T*&D2i&W$h7U#yGVJZfVvo1AOX6Zc40o150%?Ck8Q^Z0QAzE9p9 Zzx;4i2F=Bqos&fiV+g{Jbx8nF005VpzB~W` diff --git a/files/algorithms/recursion/karel-1.tar.bz2 b/files/algorithms/recursion/karel-1.tar.bz2 index b21e82ab3d6b3929b84055da62b104b137a341fc..770c6b3f6b764328f50f2b693021ee4535f7c2cb 100644 GIT binary patch literal 5871 zcmV*M7H*NEIw(MQ+4|E5-u-CMEb*C!5p7)%f9Zk<^#)IDI^Sw=UGEuhG?r(7L zd)r#72S*?~mUdaTqb0G=XNtFOl|Z+32~8lG0GSg*L}5+pWQL%6A*Lfo>O<5$AR1^7 zQ$y4m2~7ml(1NM@rt&pUYM!U+dK7I(r2SE}nKU#5Mu(^X0005N&@=-;(9i*)kkdd7 zGy^~YWHA5+f=wi$q}0i@QwFFuq3Rx|skIsa83B+0&}bR}03uNlq|F5$B#%rIVX3tl z3~4<^jRu(pX*32#hMHmki6H_4XhsM|CQ~HvN%~BokkDw*GyrG-0snp=rV0WQ9$(fF z1l$EIu(TAQ2|!s zIi%5_I&otER{NMtDrE~1unb*wE5iwP*u&A~RV{-K)Q=6bid=sqksk}+MMpQoFd-dB zq~3J(oWP;o`EnqSzW2Ai+u3+z`bP=djK*IT$|*+;@m5|fwB1?RuX~p7cSiRYqc>f7 zB<+nGy#7WKp5-NwAbVwNohOAgbhJ-hykSziD*jZZv!u=d^lp-r4=K|j2~Wl2vr&q0 zm|(`QB=n)}+l97DTwN74kYNu*|{m5HkcqOrav7 zBB4G*ak8PdqK39mEfUlOIw>H16TLP7>o}AXF}S|nf@Ku2_JJL?+il!zaN}qKR0Rnn zR3uaA%#_`G|?Lbkh*D}7+|B!5I)sT;>ow7f z0=o3UK>OCUg+!$T3fVX&*l!J`O{Jvt3Z`p|0ZhrlOc5uRisj{ZLuiU#Bdf91&s$yd z@s(&z$GdxISF@sX4EJ-h1{B1Y`o0=ZWQerLj#y7yA7Niz^unO3PTJ!sz$7N?2e}wr zInzX_<(c@Bv(%@NY(}nYqK`HLs_mDtW+Gt zA>cx$3U#cHcHFFs;}>+G^U04t0qoCZD2_ACt!qKknn)scDYtGo8>hnH-ip@A?mf9S z0|op&E|}f1bw^1A0@!GV7$BTr_eBGjlcTqi^MTLN-0>pv{9m|P*2^^Zb@BFpuV)^! zzv-r!8kpw~9^MKKWVPw6;OnIOG%5BAJ}-~u`C#u3D$}th{BCxTApw#f=7IU@>1VIO zY#j3fzc=2@zu62jVPQlf8>l}wq5Q#4KlgDDN!$lYPZp0KtIrkR>g6*+EJb8txl&vp zTp)(tE_F=+{Lb5O@9w$_axlb>0%<4u{@3(+6Y zgq>FjLCb=J9d#dMbP$B(8Z84oAVXap+Sr74?9w%u;!;Kf+*u*ZO4i{G3hc^=M4@@0 zlj-#R%ero9o5ie=w@1Af_jk&fPP#lC;|`{NKM8m#ys685Y9kk7()Uzc^xd+UG6vmY9`NJQ>6y&^KBjP-XeDX)>C*AV>OxN_P)uQN2K z*i&JZ;dHiqCr-nBS%ZbHV{^BA&J8Id7tLOFS*fLmE*a-!G{>}Io4{cJ1=-{wGjllO zU9>r2G*#R@iJ+k6H#?9=%;bVm9ugqh3}zQ5HNwuefVJ%{?b*wvyM+|u!ybIPGni>) z$Z0<{2*+Jr-Q6RNX=RIYF6$aNLNzwo42U(CPctnou(&eT-lo7dI-~`^N}0xO=-Wa# zM{agFXV+s%wLNEHes&F#(DnHW_X3`pL;Vi`%f-8QHDaG00uY`IohN6ZW-(t}ePKIU zI{{}S)$DdnG^!?BeV(ra)3QMzkz#C;BcvfzJ3$*MHxQ5_L2N_O%7xH3)0v+j=;kOI znJtqWc>f2h$JnLc#}OWhne|N1pGvPZ%;siuGS{CkFH9;gi%)+&MDV&93EADa$*{#H z?T#C8p8Q2(D^4N6S+FEx#v-7RgpfG|cZ7CuYXv+u0-D0RJitITX~4uOU0v>1xm5-| zBlXqDYqa>ZVSqeH7y`a%DdzEZl@B$0)_|rEQ+a3tNXZHUkW-T-9YCe|Yl5)Pf-Rw# z6wOoYiio-xA@h`!NH@zpa|JD~UA3&rAdrE?6sCw022_ez6q!i*q4)3<@>C+5x6*=- z0wO@3%Vmwpx59#@K&TQboL`&{l37A)(KeXurU8aFV;IJid%4;jDptr8ti=lg94%I^ ztoPnrHnx&93Tg^KLir$y?#nE(Vok0O_|*ugZoV^4uu}cJG7Pfb3R^)jSj507g+q~+Kq|f;#^xe&T}!` z_y{_&s_YWh33((^_8158d)w;vZnvxC_JXm&SdNQ56y*YZF#>R*o9i7Ov^A-_- z!-(S^pKjt|&PkH!L{~-V$Jy`)N*+**g1*rEVtGFzh?Z_?>)|pgsz95~SWbMTPJGU^ z(<`H?Cc9Ix>=3jr9m3J(u>YNe&-p6($T^SR_JvxA?2-; zyhlsdM}9A`MXWJB>Wh zx!@0ys}SH?Dv0DMS8n)z4ly=9`f@$fAmn(uBN53C38Qi@3Otw?3>XZXyZ7V<;xl|G z!D|w7TRS&*77aAjv!e!*G-mHdX9tjAbu%c<)`;z0RV$1XH_dvwTH)mqBp9LRE6@sa zq!E40Do(G_O~a(QMivm3re&YLqAj zLyZTd0mPEw-Z;r4`o9kI(qHbWE2^PHi87qZO+fSF?D+!U7sOobGC1*y+}*JlwFAo_ zQUGsx9Q&>-)TU?~uSG6Wz~JmvxS2@2?D2LycA-6I+R#c#{wQ|%>$prkWg28r%O zxgK%qpls+_f?UT|*@2RK17Cy>$#+W=a2(*!iQ(&tr08X|$9P0?OJl%D$~bGa%?$cbe?z%cG$rzs%_h$0pE+sR1y z_eJsDBZ5-eRc(lN4m4TN*RonluZ%T-mUgDSF*23WNlRqr!h+kV0tA_9$#gLni~jSCR~qdUy05 z&D@c{$U99byj>`!CYWPE7DV!)sKWEf+4GLp*!kv>zD6bov=?|a!vRbpG6iQdfE^Q! zDQKK7%L3aw_X&iHBAuYn)EV4&2L)!X4IE5y`3@LLt|^%$+%mMzcmOu^(_XhKE z4DkX{*wzp48?0~PF?;mI3{=OFscBPJ< zx2vHZV)wH$JP5{!cULsDJW4u_3sa&oVxe){D!X8&uv0Tynhlz^Ln%N^%bF=-O%1Fq zD+b`%OVv#{M8WuNM)S#@s?-y=BApaFE!(Nmdau>fDpNY~9?%dfehhy)j)6hJ6}On_AhAy8yO(6TUCF|hWnNEsvZPA8qDd0G4v)Io%( zD|m`Gf`K7CA_R|hw%cuX4ltpDZ23eP<{keJP}pF?^uWRRESO;<^XeKPeA=czlj#Wx zku1&T_#Z5j1LBk4WdUT7Qln)NRbeDa0D+79<&M-EzyveVN$=DX5Kj>gC?IF|A1om# zEUWUw8Vd+qM{7hl(O!D@=B|(mwJ1~a%78>P0{eQEJ;j~O4)QsNxSsE`eU7C)yTOFw zFRtsb2Z8JBoJuIE>Z=hf)cEMKWQpL0ffgpb;3vGm8;BdAkDxfS=!dQG$9d2`Xfv$g z1o87h*t|X#ASxxGE8}#)dnhQP@I;9)+H>j2)boYt+vKCrSf-*M2wC;fw)hB=7EL%P z{VO0ONhs)MhoUNaA?Sd8M>elYcqZDXc&C_|(aI7>U@TmFE*?Y3kBkv6Ib$W-qmNGC ztf^08f>B7Yt3@6BC#$WK(g<+){XVX4aQ89Nlqf~tBMJuPlU@51k>eQ{RV1mt%C%FI&b!Ba7!v`qyido1Nb2pJX{@pn&x%5N=OOz zj1;gTy50?fqV~~g-|adbXKj4rV2J3Jd=(Fm6QXe)#!t;YashFMyoV$QQ$q)c^M{H< ze+5-KOK5W(5Z^+K0$C!DJCHz@!7%Zq5hQ}7N+F$sS_dFx%+5HH5f4xf)wC0aDEKxL z=|kYOuuROnOUd-6^we)Ep$#O&&`pj8;`ak**C!M~*gayJZ!blPySwJ|b(&a}ux$(3NOacD@_gddF76j@r=;(T}P(gxPkVa7#Ga%#; zq&iH6lK^3?!pAc3TaVe(6H*5H8PJHv5cnKqnOAWWoC-tU9LPfffL#uSW#T@*Z2}po z2beBQSU`*n;~3>C`S+Ow1Yv%%Oz%y)dM62@o3Lf~u8kH}(&>s> zP$Y7JP`Mz5sro~qZs43`kyb=7CSZHi=y||_XUgbYJj)d~D0NUDsB#;fFt1Y&XyF0} z2Zw86+lt6b<3)oIFELKr9#!+IqYEOSD2OmbIXT|C85Cfr zp_C0utYPL!nJE;p;K`#%)1EY72oNRRP6zA4!)|aS_8(jmFws0(bA+)-6iP-znd(zN zG1&Erx%BClyCNada-3@f-y(MMkiC8c?6hK#^~w~55ZF}kEN@cvxi6G8XNEz8P!_Qz z>J0$|aNs@4d*T%H0NVjA`elIibyZay$=*bQOQxp-cpo`L2*MzF$UO#*VNqlj!}!2; z>z$ydo}&_BLo|I}kMY&g_?X_E2^Q}smk!5Va%u7D44utbcP1U>z>GRiJ;v)&n#91U zyyTqOWx%G|Ng=@TJ_ZeeQtktw2%^~EZSL~75d%`TKzb7*q)l?r0|OHxY`os-;RC2J zIYOd@OvVCH=S;;<2&9nB^pz-})RlSytWQ{E(8;(HQv%9HA?K_tuJqOwkwhrNb1E3i z5`e|iRAKNag>9tlkm~N%-X5GG_68s;?8ln4+RNs{_V*#OpU3&4ErR+i08{FbXXXGz-c0a4E4SLEQYP$m4kv zgZY$qLQ!@Ticoc-CRdsH_LWhU9S}wi$j}ra_3~KNk=nFmzj!!_Z@HH! zpg54QLrdVZv^9hvnGAQ_V}V1B19r8K7%P<7m`z$46LX|C3e!53Oskw7ktlHq4a`w! z2w2nzheIk4#nO06bvQjPnJ-AKl6QsbC+ zGmV2-0#6CqVI7-ko?>+dEvQgL2%#`;3#YbO8-f^o$L1lZ*-?YQ=O+K4_m?rZXcu6B zbUv7xC$sW`pDJodE&_Uvo_@oK2G>B#wnVvi!dmZl*n&_dtfC+nFb82SB*mH%fYPA) zWqDVo*+@b;y~-9oEXs0+E*x|Pg*rT@uvi%_qSJ>fh)JELv zCg2hQ+)5P8mep#2n~BH1edY(L$b9K*%0%J+L;nHw0s~+;fq+w(MHm0Y+>uTcBrkw$ F{s5a!%%}hW literal 5882 zcmV*B>`{lLoF5&I>%JJwO-+SJtstavZI(l^>=&5hM>%c2~@#lJ#(B{;7YT4cM ztLXQ(wNxCA@3^-dO&TFGdWWW&LqPQaG|&J500w{n2?-NYf_R>zL8+P%rU=AhFaQBC z0WmO5FaVQEB55>gc@;lKih7==N0i8Vho}ZdKxjQcG#Y3CGysW2Oq0@LN#;~eY~KN zlmrc)uS*yR)dY)JxFkRk1O>7H0vz1Ej$!%n&CgX-RaI40QB_q{RYhb;dbRt3(l-Sx z3T6ss3P3|iR=r<5z*9WcWP&7-U?~MgLLiMO2$4jJs-9_^SfSn6F--WMzkkE_{uWze zZM6?|C#BrY{&5k`C%nxcca`J7)AbJXN$>Sjl58i7j3l#(gY)AYdE)JQdP@wTWxVK9 zqHdTA;UErFLTzYND?7r3h>M6FQ0&o=`L7N;!xc+23s|vRC9L+tCI#$NqL5akD8Y@l z9I1x_E6I=zf=+1Mx8ih+pVPMH34*3Du^Rxz(?Yy3OSZ!6I?<8U%%ZzCxKMV4{NYvE zn9q9BnIsHm%<_$5{7hI^W^KDiAKz-zwaLd;MQgsu(|R8bY1;Cyvs+CSYDiXwP0`%a zez+{ItCyCJswWC73f4a%#SaV=NEmM%)?y=4DP&VeLcrrwbrM2i*f=)$fMrBo7apt+6Y`HCKg0rCnjVfx)rZ;04%z*q3 zGN=b=Ba9i26Q0e9`y6A=Bj4f6%`ZOLN>Y@jW@ct)W@ct)W@ctyg!RR+acg(t8G>#n-& z-(z?AnSFMgSy&gn%T;P{dHnAwwh+Awt518%%AEIAfM_ zB7_K{NT^7tVklxLWs;$kp+fh#p^?W7FvlEof`pLFkWi48R45I{MMGAs$K{pd^K$ZY zi-t#l=YD^Rp6K+}#Xx@N`;Fm z7((bKxo$Nm^W6CEnX&*R1COxvr#!J~PmJ9-janH}cPs{A#gsSzoP`St6+(w0LiSWB zP^%2UhG2ZOp_zM1p%s)VX>E3YDC&+LDq({dn3$N8uLNazd;&2THIreLuomogs6`6ztqynSWf`ODImkl1U_zN^a~SgwVP3wYbqj76oPd_eMUG;wvl4wXAm%vGIJfa(VkgNVs(!K7V=K^s}gY(fvFi6yIL zV41LxtqFIbhN#iz-Q{fwxc2RA%KCWcFw18XFkegwkE7q5_#}j}0~A|^n}EmXt@dCS z1+$ImvxJJBaBUR6(auUG6c8+oyBO%B%(0vh>?Kd0E|`&0g%vayCiWJTb|}nb zunP2&U}X{~WU>cy0=w*~$sBFi+BNZ~9#=JPJa|XC=?So~<HLR2jgdyNUvh_Oak>s-)qWDGKC_M3F%e;EB)k-6-c@nZz9XUvXBWWhN zu$bF7I5&<~R7a%j*kA@C?%x+&Z`i)0wm|^48&J9kCa`n^Y20 z=7W%kgqaC4CfLa<;A0|dozwa~c1wbZ=Yb^zq%15A)98sjN@So&LAS-bs_!w7w%4T0 zmvRmM64=g`v#ahzd(e}r@01+0C^6Ak`lFbHCmkUi-`wNy?q*EDM;8X@#fBASO@nAu zjAX_%6i3Gf+o+@{yzW8U>3eljo9c<(<_FVvY3tnA3lOfe+mt5iG5Gzm_Nlz7?UohU z2Gk!(qk*Ft%SS4}igrn#a`NY%Ppg2-+d8htve!LJZ?je$%F!Vcw9@2=%8oPE?pjk% z3qztI`TDQjVER1FlAlRUMmGhr)$2Jm8)D2G>~jlUyIycNj7ORYN>F zh8On4fC00Q0ug)Yq1n(ot&B9P52iMjqMIGaBj<8KD31vcY{oJRQyO1aLqJ+}7IkXf zotp&|;=c|oc=DKMRLEyO>Jg5bJG;6^U399Yu@>|V8{rzwbwd&jRkO&)J1Q*6ZO*eR;{3X1Uv>IrV|HCuGn&)XbT7uis#+ee5nkX^mDoO$h%x2avxc~*!+3-z zgC|MZ=v9PQ*dItwR#FCCl~=LSXPr?o*Y5K0JsPAE2^J=)B00hpL#z?9lVJ%0Bo@Rx z{3u!l&eauS8RRGpCQ8)ByuYKrmyJc=mJo-IF^_y>9^1_G#6}_^-PxCePECk1ioHl( zuf(TKU{pajb)juV3S0_xmVhLTkf2f< zVwwVx56!!EnLwr#+Bm#0i;!b&;H9p9Sg4D|f*%5si3a&)ra+_(G3^B`9e1GCs3Hjh z2JljXh~B8ukxPP;DIUmun?m^A)liCU!ju$u5fTLT+Z;9-&y=dFIKa*k$T7c-&=ECE zG{)!8JzyzqDy9P3Woy#795+( zZxYhE#&em5$G^nJi^18~4;kTbVR~F=LmGo)Mup-x?6OF7K-y8BtAkM3--S~_+{{>_ z1X2};`n;Ku13-c}+Dg|&xp z>GcB+Tei*y_5$~#9lGOWr~?8E^cSHE_HYu9_Rj$k9LuvXaUWH33P}dXzh(wUxY}ij zYR1Qtak4}u7ZRm1ae!h@9a+hIa5(1zjfu?Ewlg90bZ{HQU zvr;i?2aX`50NU_7MASdY0(zq&5)1@{P(&{$xDV1o70k#D$o5}kjA#Q2+mFzv%$5>@ zkjZci)7pu0JY&j%vzcZIa}HYM1}WId#shlq5@5c>%w1 zyhyRR^#FFpMUWvCkb4U~83@3fxeMttZ>nQkmpN!yAVGwLx#^2aNbTd->_}7HYcO)yoZ7L#$2NJ!G3fdoXeM=OSo%1>alhG=5 z1FL&cLLf*|L_Pr?G}A~;Rx^hxSj{F*h7Le#L9s+JP>LGJZgT|R+~^VpkTVFG>@5@+ z0KJd67Z!-BNE4dc=!#7NT^VEykgMtedmAo;XsH4aV51_L5J0-+2g3TGE82IDukZe? z*9IjD5EUWYm5eq8aTGp{M?0RpFu_%Q0s znOtCHgJtR_ks57>1RebL9@oqP1?B}13LsM;6+%c<84$EAj1~-RJIgH+I{a+IVS@|P0|W5cFkvI`&@({# z^h`fD#3U+2vo@N*`NWtHF+LtB3nYq_8z_pa2_i@Y3@`4MI?!tX2xXd+-Jm8APcVm! z5HkG(-v~+zD*NIM1%xgmt)d&~uG;rxu5b#qC{yp10ElJ<_3~8qmUb{Z$mAZvI0bsj%G-C;-{V-cn8{XYV@aqYod3Gb`vT%LP+Wbi;qi(i0~ukf+gpa zGGDnIHut>6N^sChDHauIqrq|gdpSRlf%5(TgZ+5<2cw0wqbI5{D0wq}Z^Gv|#u6Qt z8)d4Hj%bVj4Qg%%8p{N#7)4M>l?aBZ2nZ4?!UR$lp|N1u^|+~7q3=uu^MNCz1vB)0 zx)rUg5V9A}HDala7QfpS`0Y0kJ+R*l-FK*~V8D=vJ-)pS$z@FxfI~gte*_}Odx6!{ zOpd1nq=26>f|dj}TfwkYUb-zi{f9HC>#u;=A~~g>1w-hvj-eM3Dh5G3+(>Chpo2E)> zftUE)nJlfP%M`MpNaX^ddO-_Qq8^32;%g*|vLT5s1Bp(dqzDyvY(l`$u~P*NssXIb zH@k4JCEdf*0tX+9R>Qp&kee~0!H63sIoD&$(nH3niuwb3W*$R7KgPXd?lpVeSBVCQ z#yAiX?%c5K=9wFk_EQDvGI1lqTk3}v8$*U=+lTD445Jv({253oXmC2L3R4teWK;za z1_*}-9XBH)j1>7ypk`HL4=PMzQYmA(lO|E8JTxr=1PNn|**(})Yn}w0Ct?Y3UYeRY zLRh24Fuqtq(p&z?GJh=)$qp6SIVc<=UNgj8Yzgg&{;WRQ@H74808%7O)TSS|b8UhI5;2zaI(F%BgYk*6BBEWfas;W4Xyom&tO%2A-J_QgX2!Yx` z<}`5%iy*ci#sjBR>jgV%F(wKbBjxA#Z1m<6rQDkni=XqIxfvH_k9)!rL6HIde zz+z%eSBu>|AaV=`7*tS+kibeiQz28rDI_v|1xhG1C0>B56V5VZWY7~c0c9f)_3H~O zs%HgcQ3^28l?*b(pfPgQ7<@`0TWLDvIQX--f2#yMG3Xq?)~blHNhAp*4RWQk;gRz8 zH+ue?jmn~&e|4~I% zaxgP3j`VKdV=hrZZy{iYcfhl(G=w0SjCHtUfT6yDrgMjU6~#7Y37bO^G;)TaS>;lx zm2-2dB@Pgf*u@rrg^d7+hmWI|Ig(_dootZK#fvE&buc_vu${dC`3h6BugeQ*zk3A6 zR97<9rK&6>qk;z*0&OysA=IHL4`stXW`W1n_D-fjRaP62O3D!imV})g*mVRYR&yvR zM%{)^gkv@-amYKFzQLpcCxq!?9b0FXLUIf(pio2zp)fWD)7dPI!3-Y5_sD2ARABBn z$+z$x;^rFlfp!Q7GvgC9_5MIp-kK5%fKMZzZ$o$nw?N0PM7ejuTJLw0)mq97MA z1EDS?!p#XlXHb0-ylc^HWFZ`$jDr(kaVtpg_B)UYcAV4b_8d~mFs2^<7$6A2I&E>zb%g4dl1 zq=B0C`m%TV2Oi-QU7kL9knU1Ii6KYnF6p5ph7JkomhKLL8Csg5%bADw zzIE5V@BQ)K_s{v(UVEQkoU_h4XER0NqW$B;JT%!){3Tqo3iH92FVRUMGn}*GMd&6) z@_kiz9ADxcxBg=#5Vox}5l$Pan=oUa#Mv>}B+*$iM34!-JNOzpt?wvM%K zI7JDAD0k8lae?%xVY77o3Ira};`KHj+LAM{J`j<+d(!JTcXKjiN5(>i`MI z<=au4obOPWUGcG;K)3YE2cAe*-9)bz~7|iyRxF!^;}; zYZPU6Bddq!u&iS#M>WnT`8y>R!PfHg>ChwX1>!K6x$65Zggm|~WD;7M+M$6Vd08d< zSTSr>98U4*-sIRxEAK#q!NG!bLVLw+Z~TCNE@$&rnJu_@GTtLtEpyGb zR*SbK#Vyt1m`gdJpJDQqWRSK=iW6arC2!Q(6SW3B_2`#z5POsLX*;hhc^sA8DRt+b zSk@1eEONX*z9MNh!9@8o0Pv_#^iM<25+IFouo$Zh=GSe#Jm^H*Iyb**+8YKmWCG2u zHxLpuj-i&MO|_s9QVR`qM)I4d9~HCdf9CF)PB8aq0>V=rW<_ZyIZ7kSHu2%IEWz3z zdxzPE)2WSz){D;4Nd|7jPP(NR64!!>t1=1j2MS^g<-;rhr(_`B6XUA+#T_RQ#?wcT z&z|VXm^W`Y)B3g4K>o5Wzg@H8nEDcqpWdA^H%ANFlbFD$)fp3*G<7E!m1WI)vL`21 zLXXqibV2Q(SkU~*ygOtLwU!pG*V#G+rRUCQ7-hIbsRQXn^ag{Wev&V;?iStvJKJ+x zZB<^ye78Jrx6>hPn0jUK#AVEWCcH%ILqe5tJf@$YM}4P@`pVLmU3^*HFlVyJ{V%-) z*jD+TKO$#N8wMH+aOyL(G~FAal`4B_Axn)`nswM;DervP-&?#qD&Q_xNUtn6ze?8& zsc*MXkFb}xA~*g%4AtYw@~G9$ikt}*aW`X)sA^5e#E1Vp+ntF?DWN!Z?0z&RL0l}j zQ7f8K8-pqB{`q7O=4!%b%AFjEK)?FQnnx-?q&SmCY_jf^AY2y-TncOo8X0Yx05njo zs`1Y)49S|_Rzrn<%36l+y~b*JJpD96OMvl0QPeSMfH@k@yt(epWcnG;LUvu?nse3x z|CT_M_LgGKE51&Z>Z!h*cGbc(`fha@3CA_M_fiONfU;=_`Ze|fW@d589hU$euRq;< ztXXE}j{!)-u?E;VfutYgc6zxp&6J=MB@x!K;sVcEwFq;&l{8VOuU7e^5Y*)$q?kHJ z@-@xhWiE19D5N-Zo-s{%hS)@{TuQODjtxGQC%J`H5NA9SOsV^ukb4*)HYhNg?qmFT6q}W=B!nABpAVs;<$)Y_$JQVka48JC%kk!eh<=PRe#s#U2651so; zf3lzN${0-tuMh&gj;E|ny6Q?!xO&H`m&{xZG@$xEQYt)bOOP258tvRZHTo9ugoxd| zE3`4GI=NG>3L7X2VgK07i(XAmGNQ$1ojPhHI(DhUhF`XGq&N5C-E`8N!BrHyDlY1+ zRkCcJ|3RPf-O|NQ?!?9MUPYp%ODB6~!4@*VZW*Vv`tC>F0-kf1faknI6W{RdRsS){ zL`(O0gQ)|h4>YXE0pBBYD1jI4NW>kA!$vCW+fZgIXA1qRT;*I^C;ODNkH%RBlt=Q# zmuTv{yOfBPsM+SzV*@3+nxx(!%HZza3~@5}tdCDkE~T*tq93FujLz|~-%XLFpVZ0G zwj}*zf6+)&N&qYVwUf{-4nsA2IZVhAZI&-FJOkWd1CGI%IwoS2(oCT`ZVZ z*^Y&Z5udl&%FEt|nF9ox0AhxxsxuOQfuaU4);{m5`VM z@TnCe4ca#bz5M}oP@Y^oSusCayzN*9L4mpar^AWUK810+p zF1zT7(wAzxadNBp;82m;-+!Fl?x&?)rEgMIn(wc(0PnyN(gv<@zlcZdl?2U2VHi)y zr<|>0MS?ukO{tT{G6@7(OtMmt4w#<{YfyQT3pMsq9b2ljODqD02T$0qVW3cCq zk4UP0&6}ImPY-B!yBbW%zq5B0LzeL_c-bSm0%69G{*YI#&DOjNxdCfEKogG+eC(h7 z*%p+A6Z3%DRETdiUt>-MY`sBalM1tAWu{n2YBmNxRxolo#1)a$MazJ3?DOcC#M|5w zUJjM_AO0+ORR=Jg)K;c7IYd30s8{%YV08M0pU=>%LJN24?^iw*6F6>^=Sd(ZZQO;0-z7w?1+Qq-8C(TKChew7gw~j$S#9WF~aA7~EbX zxtXw=B){pQ*B?M)Tfu>PHOg3%X|l>y>EMhCksG_Myi&3#Ubh-=hEaFnPS66Rq%gO4jAUG*D*`uGdvw}~N4CN*q*n*}`+7^eVksDm zi!BVzN9*Lv0P*6v!HBIC2HJIz*Fq}(_Qvk+omQUj36m&=2K_g5ubVJLu9K{ceuSu) z>AI)$$Ut#AozP^h$A>|`W%nze)#52G2*tvKR26BfkWs={!n z5)zue7&Sd|#r876p<_kj>wj%=wN#)8or4Fxr>dfoi&Ttr;uF}4QWhug_TXBAWC(21 z2i1yu)&~$Ptr1%^bGj7qL-JM}Dj8eewK9w(>ot4@zG5ouZd`4otlT3qgKIA27|E}i zyzqi}WI>iIHpM&bSa~_J_CGh{nE%id^5tz`&a_)c7;Wkci8W={D+Lf5ZrD(11Sf+j zp?GP!$4Z@_R9~8I)gtjDSN1=Cniw6S036v02b#I@Y`ucyvBnk!2BUB1Q2b6I6oL`W zIfUUGH=ZgQK9M^w!q@ABzTuS>(#0w^)`pQ#v$mTNkCq+SP09sqrpXM^YQaoi;8NE| zMHWSGpf6FUCrx)S(X|*P{ZxnCJ}I~&RcRHF#c=M^PM4N^sL*in?Pf+Sd*sA1Q~n& zN;J!n8jiM&eqzQUNWU+(B9Ub6# zx4V5g?VZ74@Ehau70)%qx8PMKbWBuGB(fy@x_WoYPZIgK6~y1Myz7XlP^a-eEvN!c z{L+OQf$T7ELNqLFStno&)!;31y}dl`y@az-U7t4D^$QZMaGWHIg9sg^fDgDmnhd7) zinQp%krI{r<%Mx#nn`g@`?kF#y_7kX<=1`1;XTGH%gQo5`4tNz{RS1OQaJiDjksyK zb!<7y0Y0*D@}0Eh09iD*(O$x7$HI}_0fq~mU;BYdlbSZZ!!NSBOpI?TRh*m5#h$`S z!+95<4u3EYp)}EI3>syIB_B8IKsEFQM#t@hEo}%#G%M`YfBX#97JF3kb3cZ8>rSX& z#7-;tlc}|CXtg6NiNJHNi?Em9+*MwF8492h#)ls|WLYFgRQBUyjCk5`E)Z4768NQc zQz(?DrZUf+1~#qFKjlB}ijSdR>l&p!7eS{cXNYCnCtK}AK1F#-oV689j`W61O{k3- z6n0M$N@fe4%t4&5V#9>h=WrU!@&C-2Rj%_Dbrj&;V~+}rDyZRB@0vNx#cNOZy-F{v zljyAB{JKd=HK6Dd{b>h-Zz#OXoDbm80i2O<=_27BkbNS*!TJ0bY^KQKai5@<(!Q-U zaP+fi?*=%4iUd-pwsU@<{e1D7)H`f&UU}fHR_n0t+=apE3#*IgRF-o2QE~|54rwg1 zk+#TROXNI3@vWDZR~U5g50!~IP!SfvFAH7%Eh$cWFBw`sNkx30W=gMIfNf0{% zcv-tx3#`Z$e>bbk)*CgW;h;W3x|uv^Da%sI-eUDbR@0(gz6GGbI$4%W%@ww8&o7n$ zFkZgOF&q@t`|M6{^uvBj-!vK#!P<4<#uatJR-JrHG;fmAD3bj>(h>mB-^ftF8y=b+ zPE{^35mK1-nt#LCCo_A84#bej+G-bRkHX3bb5tsz%VR3r+!5rV*>`~bmQ}4EYg?M= zt|<)`9Hx$%C3`yt_>48%_6SyJz}T%NBCUIED@XdKKFgPMrcdTwd#E9obKQLi{`=CT zk_o615mzMKWU##8CZil5eTDYM=Z(K9-*o455{gLGgl`NQ-2&XJR-b{GgQ;@|PtML> zIKKot{SX-9TutAqBB`{XRG@hOBnNwIcCAdfU1L9NO-)L6i;uETIke{D@i}ws4yhU? zm@(JIDcD$Vq(xd4cCT^0H` zbpmie`|Pro`ZBWCb!hD7_0`r59YMVklnRfv5}IA4gwbw za$$a4duw=ezuAcHY;O3Byp2EAh=YD&@i=*0r?6Bc`Q{|5GmDfv&QlO`cS293q;$kV zrpfraBPPo>Z=6iA3_3$%kD!l^Hg-SLON0`q!2v?|yl~e{nzwEY47uj4H8%;jxSQuh z+V0H?6!+gt*r_ot1)dXx1CFI*V`%B;!0^XXpsBYMlRqH3SnkmY+!za1ZAdDw(ebvH#|4AW|e5cl+mt7?5B zEBhrOO~8=5=ux5ZnaNO>V$I;w&1r;OOmR3GGrJ^SoVA+jjU;IB=gbcFLOLiKtPxfj{v}PV@WUKBu}mNxCoMayjEzQZV$qt-lvETNeM! zdLoh%@Vh#dWj@i6Zl1JC;(Nw^R8jS<3AN4i(zaz_>2bE`71M?kiewLU24)hUV-~*h zlAoDewklnuFT2Wce0zq}87-CC)~${ATGNGDMfW{f@hS&8Gm6jp304O0w*qOY4`XD#F3$w}h-^?)g?wu2!IuGJ^cu^-Pq&9a9lFn9m6)6DJNA}rl`tLB zrHIolEx5fpF=E8Z3r*W`PJfv;!9LYkE|~*pSPS9j`tAS^qqxxjaPo*;xRM`(P5BJXm}1Ggh<|~4QZY(X|P8!m9Ko*d4$xqv+HV>27SGydWV5N$#3Qu_0UBkL8;q>feZq<79VM58qv|890i!S8YxD(n$>Tn) zWvUtp+cGSm1~ZpDf)_egF{t@LR8P5ey?BA6Dr;;M5HIpo3E!RwW#p~DSw11rvg3-KI4X@IyUJKSdEs5jzVsIHM*v!IIqRCFlhs57B8sw@zk$B5vnzoTr$V)83@dYF<05>37v9>p%LECJiI!DuY+>+Jb|iT zEpiq`dCxXDXwi_wMz>M!TsYeIpKOgT>ala*fab;{bL^4j&%r2KaAWhdn6nuVV@Hf$ z2WmCU?)F&f>dMFD?rt2Ci}_Ky`D7>U$)#g`>cK0T5R!YgyMw6l*N7&KRr4>5e*Qg@ zz6a<5r~3~PlB+dUGl}0lOvpj83!5*mCug$ZjqDlAK?;uyOfx3B!xcoEnFvu0Gb^KbSyZ7QjipYB3 z9~<5uKi<7Q{y>5}M4^6=4sC#8>);kvknLVeEim5yy3dKxWJC!gJ5&oc zz)`0tXXLm7M;w?Q1!J8;bO3L_m-k?nf0e-U?xlQ@9i##X*u%70%tWX*o*`82H4JwP z;j)2hkrzicaG=JwQO?2t0)Cf-vO5C{KS=s@jp9v+Mg6U~k)r=5fqZ`tPF3nhU2dWl z?{h}~7mtCT|B~~73qjRBm;mcTc}2M2yJ#VEMp29Z37d^_`A^t!)L$q60UL@!Qf;9O z@Bc@}Ut(;?s|O-Q4@4d^9*F##A-?}G#P&Z75k}elry>70vA=$(-7_s*qu%_t{vFi6 z>HiCRhWZ!m8rbDwA-Mms3;v&$t)bu=OQ@^62eB7mmVymfcfh<-FRH66#~le9tU~#> zAYFoqK|iIKP+vuli+&%dU{>=n9z@}E3%FxRM5%?LwF=StBhoQJB3Reo(NC-x;LGyx zod~R3Or_oqax*QIpuy+lYnaG9s?BtM9n4~Vi)wH?jaY7;KmWRdeSo2S&vNcShJCnr zI{C{W1l5CVk3fxmdyRtO#^k%Iq>+gZQX-(W0F?pQN%LEBeS|>etmEHa@<)N3$?(@7 zs=*M&ml)@)hM}JX+%X06toU+4vCuxZDGEY?FFt^}WJ!`MmRle&zQ^0tCx z6RZ0g(Md3-Cm-6fR758VZ(!{K5Yw?-sR=%A36HkiXDS$SIkGD@%bxke`)oIs(mu3b z4L7lr^O0jkAJo=fv|cJCHFolJ5yxB04l+mIle$@9Y@joqaS|nZwxyqj|83o`&T|Q9 zhA=~3?`JnCNx1uq|85u%B}|n0Qv`s{>mTuT#Ou(hV|A2ys*$t5`91RY87h4FDhq19 zqVTMMdI3rv+Yc(j&Uer3%+l_E7KC2%ig>8gZO^a3`02huD+MZIABeDXL+P(~%=05i z7{9DM?BMLLJC=Wr!+Y-y%4gZvb$GkjhZ3W?4kK#T*Gte%nYu4*K+=>{ojrP*|EN<_M(yM8p%Y+%zN-O>^p5J~Cok`UY=-QA7A_uzB> zd0sqgoq09uvu5U+`b>fZfeJ39juX^Gs$-=TwvUhrl!MNkpN=l|hG_-TcwqRt1H_XqS4(E!YcK zU0p3(*z?5e*!6gE?Hgf|@PqMF0r9r$x_qcV!8mfhlux^vP=;125YwY;B9T2fRri+5 zTOR7b`+<3bdw15pi1jleSAjZVc%Vw#9%n2eZ%ogcf5MD?13e7^*xEWSRMkd8j5=8; z%HVW@=Pcw4c+p|xIBRq7M$f~L5rN>{wz`yM(KTyqiPLmsa^Tp)<(jkRC7)+|{?sO} z74|fXb5BsM7d96~vWq-ao~9Tc#WLgkp7e?orf|jVYQei6hl^75QEtf$xuqM49El*O z*LzEgDv`=?O1=^NDeHBi7(ZW%JkU6pvwTW~N0&`{mqnfAj1Mw}aov{n_$1LwXMm;3 z?I=X zA0>BbKDLHGop@b~>Hr`_m5B(abv%F2C%f{!Jq{;KTkgD(LZT+;#Jms`XYVsxS{#1a zn#e`{ww}mp4Yl|h&d9}r9Wui}pEt449Y?-Gm!*1KC zy0!Q7{@c*)2WoFKI>%vC6?CGVq!8=r0nS1wH@Pon3U)vh{NV7OQdtVKn>pV|YE7z5 z6KmU*oM<_Bl1e0lMQ=5_P_Xe8S7C*a=27s$pTbd#bL1qfdqyP;TRjSzD!JR-`M0P$ zq9CN=_Y5Z>TX7Zi?ARp~7qm!UT3Le2kT(3eCYbU7fB%I##p2*cWu%YL%Ph7>e);IB zKiC#LZOSXAp8mo`>Wn2%W#EpF!FVorzO`MgB~C|O9;o!uvIC*(A5G6fo`!65zA`jC zaPYEINPo4~B1W!)RV0bn&;f5s1dwrZ5AAu$JeW_Eu3M_$)NZw`JRVtfeXI;^aiY4eb zVjl~n*E7?*hL}AZeUT_VQgw)*S_4WW(tjfJ&n`(tJ*pdeVs_i4htul-zF|EJ4s4&j z-mKsF*iq8uH^hfBDo`f*5$~Co>y?QNG29^$3CTMF-k8jx1W`X%OSMYahPZZzyGpA& zkc*9K5n3oyeEXIEeCf@Vpj-R1X-5`*OX5RK z$$Ok*c&U22c6l^mBgs%g>VpSqUFnhZQ=kdoxh7$TV<~)TZLBf5CP)CiPubLCtJ;{ol4?bx&1P&KIaTE}@ zQ5Ao1PmBtq#_2J!LrS3?nZja9@`CyhceAFt`BT;K`0mXuWFl?HQuK(zV_X8cu@V{- zf8;nM?&3#N^=6Y&yvaW539h|s#L&`5f`=Y-GcQ|c+xXBo&^uq^S?Q+5+B9Q8D zc$Fl2a23SFIaSLKSz=A->&?sJD+x8!C9mRHRWt0gf>y!(0Bykz$w1&Fy8NCTxP9zo z-?!g**th{I%gW=g;#U9#*q=RW@OGg}_2L|&64J1qY%R*DtEc(9CZdAh$o$1NMC+~T z6;@j-HA(!IY|-f07-10tR!m)`SDTj79M$`q@n^7DL`Anj*9h4`0tb6*7{%Gayn&je zAZ9|U0A+hG-dyrnq1i)lCegVw%1G9p$ma$&y~q{tS_3FFZjH_eFPM=HWWH9gS}5v< zUcwR*ihfa!gPpE=oX)Lr5atNpDpoXX$A{}14-CP`YPUeygj6%=T;$;~7GagftFPFM z^oNk=y7zyX382X;fM@K9(J*5y**XZkV!KwLxqg18CHl}T_1sB)9FioZ>?mi(0+3Rk zXa8tI9@Lfm>Y#p^({`aFy3LFci|i5aIQa37zpGW~3@!PU^OweuJLVszBAk0EWD%=B zPJ#Hzanq>p`l5; zv3_ z(H>$S+Z;4{-$X5%uQp~=rf!$EOm(@2C${3h$>kNckXki*VU|6}&OeI^wj2NYvK9T{ z2JxF`|Jb_^OhE+#(RT18R5X*?wLtLl!^2HF%gK9eC4orR@bBt?$Fj|@R8LLAlFn^q zf8Sq%zm^hr{+NCqFqVlUw0knIL**{W<1L9?+HLgSg`G17!3YZU9HQ^}^OBrDG_QxJ z6RDQzfwNQarLjgYq7eCnUIwF#q&=<} zx%GZY)#Eor-Lh5;P2W@&-R26JFn!L;dyc?Ijiw z44TH>wphz3)Am!gXeQ!EztkTwYxsbazI6H`NHr?2!UbAvSZZa$dI{D}pC`2RMQB5{ zjimOWz{{~+5{OJAR3$S=iAIx;HsB6(*0VX3p3SnxqhS0z(y;!7VA1LQ;1G*er0XVi zZ;O@cB7sa%ggeeR$t34sC4xyOT=|PfQeD&r{gE8YQikcH>f*s#Fj&sgDPQLeB6YVB zJXk)ev!{RaO-2Sm7);>SGP}Q`KWKew<9Ce8oq3X*Op_DXPcu2(-@?Usu;3S$lxCA` zhSSJ`-B^jOSC+%zGO07VyXWkY<FPRY2bt!40bNa}Fwb3B67e_Oq zOI06ggFCX?4Z_&>XeX||@o}&`?Kf~BI60Y0KW1|$!PD6KOiu4k*DMP`>FN`TSfkdu zw%Eb9e4(~CAoQg%6~uKXYsOombd8QWHiLC$>VxdBFhx+{c;&h&uZ5eJ{_(b?DtA1Y?xpy=sPQ&C90~eL|DAJtYe1S`UESK%`8fb1j z=ude-mc5PreD{yxBToESn*(JepFJ0|u8QwG0hQ!tRtqRJ2f3R2{_dzWd*MBqU7=|K z_S`}Js&kd1m(aURS8FF?O@cGC!)bpBV+`ZARW7d<1Ahl1`CPF*2ZBpM5*_T5N-k$1 zY(9?QC#Sqej<;InG4e2lA0W-W3#@3kq#Ql1T6hhMD*atEy^5@-cfm_5G)|85FI7cp z64oXJ65CbTxRS&m|CZV{sv>$-cTcZU)UUA}=6o+L8VsMPRYF_{xMl2&B$^*DL%T?P zRGcIWkX(oRaemqtj13RbY-uhWASq3$S^15!XLcJI-c>0(Hk%65t-vUaYNgY9yU;ko z3r*3p!5v&Ho~4R;RdQK7Hi8ybcw=f`ci&z2m1qc~vh^K|GxY!Aj{w=Ihq@bEYN1uz zzk0#T#IY6OS%9M~5Ihn{Du}guWCt}%6nisRhLUkKqESs{042TU4r7a*d-ERbxP|K8 z|4rI-87fT$>VamvlRG25VHTl&C&=U^7)VmNiQW7Wefxeg_Pg-3D|_!+_Rwo|xGujO09# zc4M)*D~5NST?k9%w=;pjR22ZluE$58^2Qpz23^^ahn|hmOtw&{sq@kOIK9ow>+fZL zoh&TgN-X^`P-WTd+>@|Yn|Osc(NjFFZA48x3Uz*RcU?;i&V?V0;{I*@yH24MeiGdH z&{zh2aa{ZS=cSV+Grnk(Gu+Lny@b*0n1u)Lp0VhcLXmD@IA9+eNY@+YT-}+-anUp9 z=-SCzXMC5xspggw-S%a_+aoUc6a~qOTGlxG%i^X*LbL9G-b~wqXq;?fT6}-AR`Y`@ zjwx%rK6=)freu>@*q#EHM(!NwbsKKSbl8u+)Y+dBJ!W4n80LEOx3Qo(I%MNvY?T1v zYRO2uS-ib(P|b(6nrZ$J`rZt0{G6*-M-I_Uqx$&w+r>MG zpP}=+*#lKXXd_ik69eI(cg?r1a--G-x?f}KyCOD6i+MA9>Y0|fW_hv>lu-vbUzKAO z?0wRu8{=&($In{+h${1{`{0eSXUnuAG}U~f|2N;BOl}lQUD6oQ{-()A6G4inC{58^ z49%UZbe?IT%hYxrx($z55StlZ?BpU9*4yJpv^R)+4Y<~zyAVb`m2t;wM|BR{A36dg zN@omLn!gF%QG6_F$$v)f4%(|w*4J3KXlLuY z9jJp|7(JM3a6aE(M9gmEraqAT$0eiIle*bwOM~yZXzh_3J}8yzdFHNWNWB=p)XGri z%s5x-)NMe+J8!cW`rVNKY~3!wM#>!IgaX-{^^+q$(t8Lw-8?(tE|I}+IzOw zu~{-WRp)TiU>}%q%K7Uv>Y5ld9~i5`Uh>6Cq34&yXD*vkmUYEOYJPdZUH$bww67{8 zG}0DPwaeao*bMR_#z#4p&VyDip3dLU?aQrlq|0DbslBsGtq-~n1-N=&n9lx?=&R^t z#QO*^pBXO>?(xB|`=>7%{A*URFHNSzIvOy0;o3grpZ_7hy-_R~o{@b)bDm=x!J^lj z&3~A_)oFX>IzIe+m4NKBvSIDRr+W2cKji^AC%xGMHgdh7cij-zDxA|oc9JskR`1cz zzuGXWgRp6q-(f5cCL@BpaVWS`dlODuStB<3s-q8nBO>X@WWR*PM}H2Kj#h;ygh&cr zZOU{>gj*sKY|{)i^H}t@lwBKk<8IL|BM65vb=gwg7w^{8OuS_pVR3*AmGXq(s`xJ+ z{;+(poszS4{d% zWkfo&$ZLp8tDsC?K0(in8u`*lHP=2QNn?wEY0Gs;gN{93B~42QC$TAcV_^CP&9&>M z0sq?#k@aMjUv2^C#Dbj%g^mUbhAL`TOGGa2ho zUoM@xv>O`%ho_86Yx)xzofV5uXz|CQa0dPtRswnB;(Bp@+kUQ;RLgl&bN4)Vu{&sC zjvapWi8e9g5jo;`t@5(_n^OZ? z)WXn=9mh-o@}DfzO_dUP+>L8tJRCK4s}aOkx=yDkM1oa3NH080n%-VjdyPlt;bdQd z4cd*XRj|{1rG5EfG;>RN`-hz5ph)d6x=E2}@=c}SHo<@DavWj|-wa>i<+n$(eiaF> zjLj4y^VJpKbm2E}?^CNYXC+Zk4q0BG-04oq9shZPR*rV8%9?>uFmyP`abe~|y4Rnl z$gX~>Q3J76Gqd5~l?W{QKnB-C~nZ(9N6XHxN_S&i&#D<-rUlNsEoHrE2_a_vV zQCZ5rwnd)dqPYjAo~^NTbXPGREwSCy$3rB)g+0GF98b}uD-NU6n0u?{#j4IPSThlx z@C@!_JUCc19^9=BE*hBgdBvz~`rq?IbP_s&SV_aBJ?aLQn86c^*^|zjd==nvXF0IZ z1_JmHxhUc(kv)A*C~7x2dew?vbQ;`g3D0dhjyXW|fs$OWUgNeN*C4f>?*zDt2i>^* zBtjLx?fpir`Cey^%;*R^_W747V9L~le=Z#tPc9uD=_0tyrE4G@E^B<25Vti^awZ6^ z0#=;jpH4nJuAppQK_>PAyx=NeqEP{OQTgPIbbh~5ci$*Z-a9_Z%tw{fF~;l&t?d@c`oNaM|eq0E2NsFu+gnsZ%rm z0C>9Ig~0a#X1Z^{bMp2%>Av0ta%X{eQpUhP50G>zIM91E1<3~Lo_U>dzzN~*eJA)1 zA_&+pCcq(7z{;!1D@e>aaCisE|Mx1STfqDU@Rub1JcMoX65{+k=D84*^LytFpcSR% z$yxm=Zyb1jGhM9=0A83Lk1M$klFuB9f6sAzn)rV>4|#t%fBvJQzvSoSzqkK-1gN`{ zqzZ0(TDS$?JUji60@zFdAS9p1#xua^SzjY7Fp&%V*VeM0ZoWS!`~S0^>&?Hbjz4qI z|GzjF5W)Y=*#;c{or1!DDInm!0w$lOU_DEDPW+z!9`=9A7r%q}T|Yqn%l;(<;&%=_ zYq9>{`v0AT5+DLH{nQB`JpqoMZ_?z|O8H||a5)h19N$4o>7H!hKwKAn{O!&LL}S7a z_VHseq7XhRdZCnFc$L}&!%uo*oB55O<(fc#rs#$yFl{gDGk-Vu$63|@d_y#57Z8T@EFhvt0 z#dIQ>nt!Zf6UI=+{bWe&b~oKw4;`~v*OaW1+=o7@ni6a-+GM6m9>*Xkf+!`=l|mu% z^6>lu-1+AqMJ)P2SZZk%8Nb{+sa;Lm*4PCn56>kglj~vQa7$7j>FKi03mBEAH`cdy z`d4pE-?|_$QE1j;FhUd;GrIf{2K|+xUyPhfgc!2Mih|-jW$xM4EgN^1Vo0OVtKR=< zC#49Jp8f_94_x}LKb>O>7forcX4hL}3AxJH{7ASzu63Q<<44^WB%}}MlE`u4?*R#9 z6mOs$r-x#P#N8(`m&337eEtuiCUb1oeM(o;=q8#EBU(b_8-ng#QDF C`$eh% diff --git a/files/algorithms/recursion/pyramid-slide-down.tar.bz2 b/files/algorithms/recursion/pyramid-slide-down.tar.bz2 index b2ebc349bef57beca541a1e34623cd76bb28ced8..7952f54d7a1bcfddffc2507f922ffd6c8bd00ed1 100644 GIT binary patch delta 1295 zcmV+q1@QWe42uj7LRx4!F+o`-Q(04PP#2L7ntzDIrpUfo&8n)PRzykF;_mU>vDh|bp_t|*qD6}$A2N5v6-6pjbMd7ptKLP6mKL#8 zt5mfuVxibzrLM&BTFF-}j8#>au@)$jiX-`c>dm37ksFGM3CvO=MkGleZ{g|>q=hqBgEM^gB-)6vMddE^-={J5JKaaJffuk%PFggF_=SjLl6885B{W zcPX%N(bH;3b{{r*%6I5#lU$ znw~SpWMnr9?mj;suj7G{MH)0W@*H#j7vwJDDJ)T;nMat^u|V$0Sk$75Ha0Xe85C=+h}ffAHxx@78-@xnRjgWxTt$g$ z6B`*BoD9w8V+O{iW@iG6m^K$ITrN>2@`eQs#Tgrojg5^BjSWo=#>Rz>jKO14#f^-O z41XDvNX*Qz{k`$$^4rhnv|gfj)t~IOs{HmZj{G<8HJ)E}|46CqqSCJ)5s(TJ6tZLk zxP+)kvLty-+O|L<2tW#imh1)u31N)T#Qrk0ztpd@-I2>a52#EZV1BWz({~GHyZ&dr z|FgfJ?=2@CB7&jt#V=AX^i~VKezW#lrhoqUi?2;pYx=U8+TrWZLaI~ko>S(YpWZ)k z=sEOe%_Mi2JqL{DEHN=7)oRUzTI)64V z2PqxngPJcTNTaalNf(H3;Z;%iGj|Tp$zzDD@glsIYxl0qUd2-^p@FO(C^d7LIZi@3 z)e9e$$D=qd8pq5^8-~(x3Y?OvxH?0Lb9BBEMh+8?+d}k}R$Ap*It4*!s*0r*+A`Ufep*P^jiV;|^}JTp7a zF2no1lY5x8DpqHh?GH$CxfM=XOGiajimlie{qvE?dcAxqdya{TE;EDm9B>Y5oc!eJ z2RVrwgJJr&$5MpTOi*MdBq~W#P;p5%l&KhcpvZ1=J;nK3!>B!NI{6KQ^E1>soM}!b z#vtDkktMq6oc=e9zKr_qxs;@lq~;9>b`l?yShsoFJ4bA+iuTcBoy0} F1;Cf2d+q=L delta 1296 zcmV+r1@HQc42%p8LRx4!F+o`-Q&}s-!km!~nt!H@DxaDY394-mRNko5+KK8KGbA>r zw9+*DkF4;PKQ^kWfmsnJkFUqqM`>c_%#<@6#FR*}WJBgo_@bz#N^X8Mr4@U~v2w!J zDwS%MrL0ss%oMfQo;z78<*|yYvi2gy5>Z5d*Y2#^8p#p3sF0k+A|zr&k@o%`p!!GN zKV^*7N%GLqEo*)>ry0#$l3R@b7c_rQsq1?sOcaz{qE3>93*xGkMT?YRu_F{*q6#RA z6iFzeN+^*<6i|vND4{5#D56nBqtrOuoz=(7zwZ1r$3A@?AEae5m7DZ;9#fsZaXgfh zivcfx@oll5UD@!FrnO@ImsiWDt9LXxDJKx_dLAL-J?GF^!Pa2N_#XnsXTYP{Y*Fib zdqTp(gy!?D;vNiqsKeQ7DI>+2(8DHIR9{b|dVL2AG_?9WoIGx?B{%Kq-HX>=%d+(w zG}Ap5kvcNh8r#9o3F+rMx%G13gNk9=br(4rOC5({W3*hOw8+8QSizx@nMP)&g^Y?Q z(C(8{0#1L);29S^ojFRTj)r}T^5eGq+o4Abc2AIXhI|`8LdzVdf#4;c0;g>{&l%$^ zbsC;S$Yf+U3GO~WAFtzqkwqGE95)s?=l(eP3$iIJQK6YfnB*)`VT4$rmR1|eCh~%d z79UwsIgL$C#>PfP7C4RToG-rNHx-`@;^i9_Hw%9jH=E0w%}wHs3N;umYHuh{*rBBp zD9E{Ud9h)tW zx%VGohi6S5QkJh3;9%!&Ji{S{)22we9v%nG+31txDicu3C-mlr-g}3W>CEJkgz10L zv3NO1?;IS_c`8L6XF5o{Lw^dYkHMR?b^c2nMQ4c>-Dbaf?8WR=GRhbl!Q+EhIg^y+ zBb`vO`CNK4g5j)u#G$xtClIO0DyxH}IF~m|;Ur+;IQ_IQNmXU8Rg<7p7K*5l{F z^NXzh&t%@_ElQP{<~sw@9BxHZmQvBtRbs1l1^;~HavrZ=3ZCPlVoQwR{YP*Enx{WG zIzi52M&Q_ft?}YenrVs*gv5nODoPG1CeoE74^$Zq&PTYvD|mQ=*3+wy*grEpL&W1s zaW*jq_>_q))lBE`yj}EX)oskBB#kF9XhW=!{G!FX&cWC_C1hN%u!V^q++E2O;X**K G6AEysmWcNN diff --git a/files/algorithms/recursion/pyramid-slide-down.tar.gz b/files/algorithms/recursion/pyramid-slide-down.tar.gz index d6fc0504dc7a69aaf98893a3d96eef51c45bfe10..a336fde993b7a554e69c74aa39c6340a718aa7a1 100644 GIT binary patch delta 1396 zcmV-)1&jKR3ylkq8GncRiea-*ZMRjmYO`B4*}g=m^1_6;1>3Ss5|qt<@0p8@uaHD+ z+Lg{HkO$AX&y4xTcC?PYr9V4K7XFN#%);B?`yazJ4VRyy-rwGhcd!TOh`w#}qv1M+ z_-(kZI3jG_vooO$+6WzSB1jK;MV+U05Zl7Xuu`tC5-%f4x=eFM4m|*jp#3 zhlkPX^TMCPbm1ilWOD-U4*{Y2uyiRN{2+xz7|dCcp7Uw+6V9Rzp1hn~P9TyKtgAFR zvaTc(PGAH9yA>TuzPDh(JiSIS3?)tgD8`Vfb=tpTqm8f@AP?n@!uf$($(Z@5t< zeG13NcU8~IJFJ2ki&3jk&ovxlrk8hE?k0^i{KKDLr>Jws1<_SaS2?b!SMfuWTXEQ_ z`WoH`DVwvnclQ3nUw^*+?bFZoaIprM1{{yz%uBC(OYg2DfAZC`B)VmthjLkq!SN}D z<~H&L*_frPI4Fwi6Z}Y7C0AZ1H=#d+rRN8o^ECE@IZgsEo+rgYI$tL#TlT_L+KW&m z?Hpa;qJr;?*Kkw_yDGK_I<@tettYa*Y;EO@9df_rc^u$y~K?9rg#+&R#|(O{@? zvzuylVKf5Mf5IU@itsAJW=A-LM^~P|z-Dnix8-f_KX2D*&R~e~_ghjocvbK_FkAXD zeGBymC}Zd?<MAdcm)YK@D4yvM~()HBrvN?*OgaC_m7pp4Bpge}o>oa7`{Fv$c5Jl|F|&gkiI; z!xQ29wv5)~5#zZbo^#N~5N$ZvHd<=J<1!5Cm#3K(hYz632Z>i=u+@Gan z4O_;*V{!OgM?a>^^WeEQ+YzJDmx~5f1}N%?0YbC73JbgYLpg7FX)U9rq$tL-A1JSu zSZZSMe+JUh(2~Il4|1lNrSXw#(a>GHbu|jH!-vEFnvxJ+5K*1~{}MAcTknni@8tiM zZR%D2Z<;Rg|Cd0C<;#(OHpkb56cQ%cn1+iI>%W4IAiWKQ*{CvA#jY|EjCzwxv^Qy_ zV%#!z3Sv4Q6_vIU(=T6YqQVD^8_$czW8*~Oe_FNjDk-a)sL(cY`Fyjy(cQvDpSopJ z0ku2F{~UdrLn6OKeu?}N`6crE|3U-*`{4OEY>)KsIs8v|OyYkpffD}{Bmb4@-?&Eq zkcV-`@&@#*StfD$4bW!pwdIyzg(H3)_PK?tDs!5k{Y5A814k_Bl3@4{u|#op%ydy^@Q3;#~ajnw3l>>})Bf)Ll9o+~2v zY6Ni)8%@u+E6ni5Tddf}E3Ve+O}EnX4&L?8l#{b!z?% z?hJ|Ksi}Hm=R{j4 z+B(tJiMCF(bs`W51OkCTAP@)y0)apv5C{YUfj}S-2m}IwKp+qZkH){gZmBH*PyhfR C?ZpiM delta 1396 zcmV-)1&jKP3y%ws8Gpz11!LGORNHM;t=jBXO|~x)s=P2EZo#%}lLTe+-+Sg_<0~W) zn|7u13FN_Z?lWV)u^p{rZ|ToYl7&BGC$sQ2`2NQ*O~d7W!u@Au5hx1)nC8-w!9Fdk5fBGu*7y8>c_SVVi z;bFA;yzr+mU3f_X*_?p;LqMoLEM1BRKS*H_26L9A=X@IdgtMrFCodncr- ztSiZc6Bt3jZbgTZ*B309r`ITkp=631g^C!QfH^@UGI)I&M(dAP9VOEwtK~K`Y!O!N zZXuGZFb19?tkG*tf5ke*^Wza1r*LwzE~cKR4{>+C%(|?v)~?Vc&IOedvG=AHTPK9qd~v9bD)8v!BFF7 zH`VIGXatsxe?xv0;Z=mqj&KN%t~`H%&EkA+%iG$2-mcS}!4Tu`x1?_Js^E8Ewe(~9 zHtG*h#xz>WXNdX@ENQCW5{8L2G&L-mhLNIG{Imo$K&NQTMPn|PMw@u(yDjMrxla*- zg^GRjf?pSd8nz_W!!Y>QLOBP&1GL^l`GFzz?3NiMfAr9WYjGKwtq_yD?mka!ga^0(7gDO1M4{n<*^ z?8z8-EDoRR=*Mz-9z54(J7P5Ya?zm507V@!Kxo!bVPSWFDCZ3?t!=iH6vcS<1Lf5g zOHB;ke?VFq+A>(-LC!R*G(K`InugnJU5!HQ@Zs>krX++HL{#Vhzr>8q)_Y_BJNdue zvy3YLw=9$R|4X36^5w`so8xOj3JH^JOv6Qq^V<<1u-3uib`9F>6b4xQQ-r|jps$_k)ER(qW252+)+Hy;&Id%x;vd7*n_jcBbUqr9YE<6lP%krNy?W`HxtbEie*Ae_r{>?_ z&Y+m_I9p6_?iLY-4SoJDpuCL%ph$iH$pjSa&IG|NsB@->U!b-~IqV00ICAU>ANo z`#^?wbKV-}(bo={3}0VffB*mjfB+TqeC;&L?8+p4p1LH7RZ&GH5|BwHPxVtk^q!&W z4FELtG}90oXwjepK*Rt5H8fIt%_>ZQ8Vvvd57htxpa1{>2B!5YnG8&Zm=hoaMvXMc z$ix}|001-zPt{2pB^d#spbZ%S00000000C@5I_?kl=hgD(w>HfNPd*i#2Gy&q|-yx zXvwl_1xW}KK{5y?)iP}am?Ilesp@{DX^?tN9*}KKG!Jj7KC}Jj_IhijCRrq?qca3v zuFQKa*qy0>9j9&Zz{pI&=2S?CP*EbjPh_6|qEJ!NQrcAwMqUh?uqDFPQIi4?zpmCT zMU0#pW{A4hV$9ky{)L;}j=h(WnP0a{?zXb*u2*Nr7D~*_$>qoZ2ZP4TE=kgk$<`7d z1XM&ekWbz2dWkthrUw88f5$-t?()&Ey^yTo_}E@m5AtIcjpbpkv(yP$?i|g`X1?Rp7$2(wnED;yH1N2a&uhS^M3`-4sDkgHfp*o zqg5SQDTUWv#Y-+Qq*-M%U7C|c44baGlMLFhjTA1s1<^_}EV5aWmQ4+qT*+d`tHl3r zgz5L5QIpQ5J@SZOz_df+op@+P?7M_o#07kmeq+nXX}-``sa}?C1$@U*uNNfw&6#Q- z5Dqnu3xCTsLTm8*0=hS|o#yA$tSuWG4}K5c1-N^~%pmXc0y*$uYXIEB4*namc9o=0 zz0xVK8iZ!;O6?`p>DukyjojxpS>M(;35k&)%~mufCPad(dowjE%+4Jh!0b7&@xuTR zq(jt_OgARQCTo$nrh-aiJmU13eAL%lW#i$`Sn3gX4;K6Iw-1S3IAqqjo!NT%AdSqm zeFk8y^qJbWaGOYS-W>&;Dvmn(GmTA$OR5IriK+G)Pcg`8-3~&E&KEc{7*hlhOgM1DV1gnPC{Ux7#^rLlEn2m7U&n|500#9}I?T;hW^}2- zK#&4J0zf1HkRc>CwU%j#MoC5nA)Q89!HGsmQZh)wNNyl2&}42MyLRlo?|a(TweNf0 z_&^{55fL4XvoonI%+A*BjFvTBb5-$JwXWGqUa@OkhD{17WtLKuQQV}mjFv1?YFdbj zqyj-gMM(vaWMKnwyxJkyKm(>oNC6=r1cZqsl1V#EQFMHB>iIZx;;QU`EFge~gXsW$ zr)X>delQ2l3eYRK74U+*L0tf@r3G*pB#(xSG-%D6 zHjLO|bjg~T=T%izn>8s#*H8l$y-QMAy}j4EvPo}pxyZW;Qwmw4?O0)>R!Jsl?s(A? z_9RaGq)#{F2`MQ^QVK$di!6l-A?Yk3ilcCO1UX>20x8wd9n-JBQwUV1#pttn4hJF7 zbCBRG%t2moIoNp`mpu)WW=Ukj4NaPbNb$gxF>tfk6XN?f|iN-SWxgt=0I>L$oz{~)Fm;o^GXK)x9fDvk|TGmys zG+4orp>piVz|pX~BDxcoffZZg2hB>PFhuhHicu1jM0A?OMsdO_&WGI*HfE*X#h&Rr z;)tG4%CZt+JqL+8@mJ>{>OABuSODtENhH5rTdzDY!wfLQl74fm4Ial8mr~2HvhRr9 zWtJz9qJ z$jLp9PeBb-Sz^hVlEcu$CmS3Y95rOP&D_b!OOi~PA;8s!$AnVN*_#}k>w8+%x`^Op zP%_F3FP# zbjr1J1Wu*ri7OD>|6rOny5SxQ+zg(%Wb#i1KU*ubb34s^S*gzzTGNY0ZiS59#g=CI(+2I-r*{Ud7)nm(a>-?vT}o3T zI3*6P4oRCeDWjC!$%BJ3?HVp*qYlXu>xxp8r896fVN8W`s5|&vZl9Co(Vp7WnvUs>mq7L4+6t5h1|3 zmrIICGG@&%@KTpN1q?9Vo4LiwDb>O^8y*>_4e~e}sY*M{+qkJ?GgTazVC2GCN@!-G zXBeXkwp`yN&8rGg&YUA*N>eqLSqa{qlX`txM zlU5VBM#NCDNle==Gg#u}+qs5ni85qLWz@*a&NaPNFi*Y4%^VTMn#I&E(SvUE?^Cw~ z+YWAnr+LGzRTy(|a874sEToyP?_tS;%2Jf2DU!=B$&rQByHfg9Xu~zq?F%wAi%r~4 z28w7j;hMIXCNu?gpx5)ZCJCVbRrPG-SIBEar7E zaDCElP16dY9`}lb3ZWu;8WCQzbgKUBxMP zbD^6x)>zSvDygtM6gN_Hb5kb+3L=asYP-2Rl=+(Vf7)I2{@<#{*GGZ!{`*>do_s5# zbanyCPci6i9$??GJ68r5VZmjfC&JC09ZdrAHpR*7#}Zy zP<$j1hs<@5poX%{%~qtB8F$v!sbWbiQkE$xOA=C2#VKv7)RKyRbuUY;K9N1mBqhm^ zm=cu!rJnFt0)%cOfT(&4lnhW}uEc9Ig4HaC;Co-8bd&3JTqz`_%n6c_G=#w^5{X$7 zU2;i+C5eQxC5d8KmL-W|Se7n&vsq-kg$ji#DSN%^LM`6=UsGa9?`7?MA0cHvRTfa$ z{_ogHIKoNxwx-#>7h^N|6jml+uijaPMHm+abMqH00<^h;v0o{~Q&5b#G`|^h z@GgQC98|%p`WJD2Sh*X9cz#hM?#9Q)wJo;q67#$9i7|+ zpaVeI8(P&>YO7k-wg|o?Ia9R{uod`0TKIujhVuZ2e1stb;9fyMim&|=PBLWXNj)## z;W&~^IWy*WG>p=A31Uh2$tG=;k{ct&(8OD3M46VdP9BjiC-xeN2n6ETs1(8#MS3NR zR6+crM!u)QNj!v{ayO9Z=E>21f@1Lpd+@(wo1s(Gr726P#!HW6o^nY)I{g*)qMzT% z$o=*$5;(GQDsobkrPTchtlJ40eBWWX72;_$^@6tr0~E*+%$FY;{@P_kc1%&OFjG~B&sFF zuq*JWItYmP@1YWsh^auMC~=>Y1-QK#;hmLLm*T_n-NXUIW&&|It#b-^_990wUaawV zA@msukg<748q<|C$!u39kfL^BdvqFIkvqpT&+7$ucVa1%!r-qdymSGy5l_x~^ZR{X z-C9xhBgVy5MdR9F%6)uN4$HjL{r8cDj0&7B%8H(quu27#L_qO za`ZGv8fFkbM()jmj{mX*xO>{leCwhjGgqS@+6%ZPX@D-nh|?GrlKdM9-k){ z&qzj@CJL@(P!1Gg3hn_LqZSUbYP7&-vj z14T5-0a{BfGZ!c$#CIx1B$GqJEQ#VtDF~uTLOcV0GJ51a|0PvbP(}n!QDBQ4UZN(J zirFMMzY!$$g>|`|pes*OYACjj&{p2)+|B6)b%Q5;ZmpZ_lFc8jnc|(F5hV2^-jc~b z0GCD^NJYXt)_sq$dCScj#p*1Eac?YOsb{v$DU1&VdwJhhbG}}lvH84pm_!G{N`4iZg43n}E zPHM?K6Ct|&IG|NsB@->U!b-~IqV00ICAU>BZu z-(B_$IS#|9oa={1gHK%m0000002i6-rkL|-Nh-Qxs8LW#QA(;lIMC2EX_2OlG6NF? z00Tg14Kf1)WC>LCl5f-0sK@{Tpa2g@0000000s(@0000D0000000000l>JnsdQC|5 zA)%qBjDRu#0i!{nG&C{*&_xjh#3l)($%N6Vnxn!;`jRv~A(PZ?L)6ViPbuJ_R8WKj z1Q29Odq#?TQ$)v#nt7!fZ9~yCdO^KV&^~^|^&j&8@%PU%Mb{)uD8=B5)83A_=}AdW zw=os(SX4`a+Nh9-NJ$W{Z^k3V>4^z1112WHXsQq?SW*grBWR^aAcY@t2*gFz#hA5g z@+7G;wm-_+o4+^IkFG=U?fF}*xt9CDD|TC|aHD5dSvG0AlStu4S!l{Cn;2m**;q~vZ8B`ZgXQ+0_4-dA()UKs zj77YpkXO30LF0~#Ga~fWvKDOtUfDZ`lTn3q0=(+;F`yOloaR=yC!o)EBmn?yn|0Ik zqcSF4Ul5)AOmVxo@W?3*4Cjgm+66WEN|r$Jc|jZXuu_0EEP>+JrsqL83GHwc%GrVz z%}VCWqswc;dpC)kjI+wDaS4f$Ak9`ZCMHCJt7|hgD$LF<8p^>_&0RByBe5&v*|Swl z`E2K@rlXt{wkyb9TT4hUzHHsMMd_#kC}FtA948KGwUfiTlzgu2Lt({GlaE zs8kgSL}7(tA|Jt&HWK}TWrz4x1tC(&Wf{KRQO{Cjlw3}=v3X!&(Nw&r@ZZV85GdN(;vB8rq$k5@; zWw6j{Tp4i8N&mcj3D7n0e22g%fbj|GJcdU>=pVV_f0#t(-C2AXebRhlkv-4oVF@&z z_thUmc_-kh)%L3_gX6`v+pnV;`Z;a3+ikY#C*FCq;qZ20m0^~cW%&-QFu^^-lv0wE zb?a^r%3yOoz!l{*#UcQELwCwS<87cI{Nboe|T z@*I@I1`~5;2fe1w_&PQ?X@RrN)!?j>O`9RmgOncd@h;~1=|9Sxnirv~Ly znU>0^n>%NQ6)@RNM#y!HoW{&B=)tibkLyoryFcUl9UdFGx|wk5%CO5R?p1N>@+(QZ zmnL4-SGluHt4tJnK6V?uj?6moZzC<8*gC34T^yV@b7_TDDyo|>!!4UMnH9;+Fsgby z9ZyobR$c}eDZ_;_%R>pAJ*>3Rq^vTfRb=Ss@L^SjY<~*fRZn|^ES%iTn?1?wSN1UB z-1Rv2xvRrg@~+Msyi6Osj4<8$6GvB7R;QOoCdSEA$>hRehFMis#B@qL+#S=ShYGGv zrp%oi8F1Z`Wi<3inPgQ}afTc^8fjZ59*O9$#kuL*zdsn{?EZt~J}yimso&ge(@$}S zH>0x(`B`b`_P1%K?6-WXQ!Z%a{4_07);MQYTJD;7{)j-*$GuBsEX>+vY8bm*}HVp*s96w z6ltec?EQ7mKBrGR zX{Up;qIe#P!ld1ot4{40RaI41%rMJl#+g=JjPY*`H)S&5!(yy;b~+ojFrHyDW;ack zLytU0ws2vwvZ|)dCK+Yso=WWN=ciXglD6|Yl1}YB9&9Uy%(T-F1IW|6hnpmM4>Ot- z!wj7bB^63==ABTlH1bxSY`oo^itIf6%=z21zm;33MP*9aUT$o=C1vFCH*U)e95uzY z%pS!ZRXiRF+0fFFO(^8c$vl#aa^sxnD-tCpX(0+RW_MH82?_ZX3jMF4 zSSzt4!G%?9ubGw#l~q+KMT$yN#FUh=N?WyBlBHMPtkzhc)F<5HLS&l>p(?*=C!iIu zks65DDjt%gg9;2P=ShxEj9G*}$JGBzDJS;4SqhR?O$oB1aS5VSN=vaOStObwV47yE zOA^GfEK3r^u`FDgvk@j_D6p#)oWBMk81;TH*yc$;2H#Wd{Kgge)WVK$`#*Uk?FlF1 z=Un%FEn#W=$tKe9SK3j6;!6sGxA{tx0a;tYSXanw6vzhafnQk)7(QaBxT*+D84y%2 zK9Yt<`4q(W1?HmAD!qQBQ?wM;+Du>=GTC4U&ME~+*bqSjEVB$!M%V>_SOx%Ojkw&B zN<81FQmP*hw+`gp$L_v0pN(srsbzNGy?m=qr-gXa#u>#KFiFshqb!aTg_` z>jc3h{X~;@HQ5em_Tn0hb9kiO#u9Y?2+}{jF=D8`vn*2*s~BVb*DT@?J?N$V!=x4C z0dlZ0P||2DG?dZXNmIjXGpXNG!7sqAn;!r9tThVNkVE zY>?oRazpl|RH~Iyw31RrEz;lPvg&5m(n%#Gl1U<}s;hQq&9$p>h0;utPqIRDSc&=d z!4jn+$_i}`)A{scv){g(;bJWES@P4c0kb`VY&IP%(B16>-=(d2c z0GH`Y33z$t)o+8O=Nfl(B%Y8wa*2SI5~Qgil1Z-q4rG$2k(4%^$AFk(Vq6I(6AVqp zN)hcIOCqF`gV`8F_L543Qb|O61Fva5X%EBmTWz5l5j(~LFm`;TPB9mnNOpd*FDNUM zdDa55^QI(}&DILj=o**2z^*{9$i$4sIfatr?kx?&tm*}Of_ep!e!()0ImkvrJ}f_r z__I6wQOY@9#7zL9K}LYDa23!B)LjA`sr8UvUWgh;HO*r~>z(wGc}dbk^u6{12u;a= z??;zBzbq$x2%VFo2IzS-aoJEjEI~W zm-~= zZ8wvu{1nrg5mSh7COkrqzZ9HwE z9!ZEB#I)o==NL|tRHO@%4(H~SZ_XG~0GV}Yl40|w#-sVu;F}GT(Fm^v**$|`7?lNR zd{4ljSPG}A^IFGoI|xH=C7g8P}ZtQ?Am?O%QsL zTt$(e)YEzK=6s{bE6 zH~FZf*XO&MW3~S4Dk%O!|A`6uZ)%#_>;HX}2_M*Z(~I?LY5-K!6kU{`Xh!-kzf2XgvP6emWk% z{_QpT^b{uESdMStJDDX~(j4c>_61r*1Z-*#L+$f#K$;HVqow%X@ z6eE0qk~jlt0K<8INN)(NPd}jJWt8=oZ;r=#WpI2Mhqvb-sA&*_wfh>M!JkJrG>JdL zX0kCZ-NcVT9G7trWibDU91;ZoMldP}K&Y^0G8}V3&#mgH;Dp}ef)RSRSXEA4x3mbr zwOH59EXe%DiZoSIjKdL_1;s$~8^?wlqFL3O5*fW=E6%{wA^LCRMw3~boD44l&kJE1 z*l`UTLv#zgW6M+k@zXfUMpO492%+)YQx|r?3tV(c`F;QH+e7s2Km6=f;s#NQeu|@* zw!Do~|N5g#t3L)wPE2q9?oK|!^#aI1))SwPo(6vcr42U zNG0w?xiny(sNG>-YsbDJV#LrkV&Cl0?(6N?x5VAIHrsutL%UB}v9F63LRUB1eZ5P% zZ?t1y)O~$3-PgOM`(``#Mcvmo(|x^5x^J~(U(|hlGu_v_r2BR&_KB$bWHa3-UDAE0 zV1InhU97XEE|yl~Vx6^ju^fgPi-6SfD#j|*v87dR1R`2pFJyQ+7qV?XxQyHRR#;nb z&g;2I8ZfULongM6XNAcE8@%3_d9yn^uUEAz4@tiHnixmloM%T>W%IprA)cXkay%nF zEa;w_%~nYlM*m5(97V;s>C#U%Lsf_gcf?jq3uz!@qQR}^D25Ko=O{LnJW(7b__A`B zBDuPav?0u<6F`U!6JSeKOpR}*2Di3?3B9!x$3bP{Mj?bUx23xF;Jf{*y4#bbwp6dN zrIRhfRcoOzb61=x%-l5*Z$zqQ=Cp9vJD^lsdFzbzxwGETq7=@02bkZ=SI?Q(HZrG$ ztKI?T&9&yVs&CYQYR$}PMg1C>Q@}=UOYv!51%s-AkXcO>pgW$$Xwxch_5LK1q%F^xB(GVk{Jd*K-9ibggnDQZ+N5#OjU`wTt(N zEwFBHWIl=09rM{P+B4JzI(WS)^M=-)onI2`NfxlGZ`5Gw&CF*-{hF9hFqe)q_eOQ_ zHw{vFqlDTgyYNN{HLcruqr||9Z5I9}F&ss=3vZObv^FVx)iQAdoNJx(MqgKV8_Sl| zsIjEDl@V1BM^q``qMKAxh*04jY9nXU;!-3JE<{{+JW`+@%i2O}v_*byGeyCwqY%t& z5Fw`yr~u&B1OaKtGQqPr9D!?ZI>^i;D55Ev)lx}JT~Wcp=?-;XU{pFd>>~^g>cR#$ z6l@@ojLlR?NRwe^*1$|_1v5*_;Y6K1K%M;m%-g$pMvw9bLwp*$i{~hL|Hd zyyFYZ!Jb=IfjQd2F$Z3^MYhD82|foYa0Q-+W*3+-nOjclr$e6QgFeg8^;Zdk#vF*(5EIFT)z+%cEbDDw7 z+z@0Ce^S?p;|xrRYR@ej{R}|omQ6Rg3%7-3(;*6R%(?Z_!Fm~HfjO{q^uwmy>Xj(V zsIw}ltNTiy)$V*x=hll=a;({=SSvakp^g~ci5slCbJGGnR^{_WwFY+bgPXw)1Std# z^q6oFI1sA{9Ei1j;6N-fa3H1_I1p0|97>dB)Y%o()qTssZiPBS<>ri4^0N@b7HdUk zBh(pscOnOSE$ZwF>gqn$mLJ>5jq&S2ptT(edu6lV(4IKV(4ICF?1+V zmQm+aP*?YPu+t887B^?C!mwuQs#q&J8==lryAwMsIl`8}<5W;r_vxSf;D)H9r@c;r zIvreiZGIwW7`me2`H`Gq=Eut0oXHuMnvcPb-V6v%==l6p4qQlQabPD>E`XQ+ORwSb z(CHsb^M68`7O}$wpw;<5nq?Z5{2zk#KL6)FN}vDp7s~(PhOFz^KW8DlivB{`KTW@s zD$8Ym6MmY06IJGTe{+1AruE1i?{8X9)9(gK9Pe=^Ptz|1${g=+@=nuy9hu|(&DUxA zl`Wa${Y}wn`aLa)<2}yGx!*(_Np6of5vQe_v$wf7EuEabO}FVxh7A|!jx%idsCB#c zsB>%XH=Sm=5BxaOX}0r{_b-EHJ0E%fl4d%SCnFfet@C77o5IJMA#=Y;F|s@Tn3G~! z2332T2h%d7+S}BZ&SblYMsRo8F00Mq|@){piI?4lQpvXrtZ8K0B9m8}c_e5Uaqsl#b;B*raQ9DXESp%+4 zCYs2R_oGTQdFb2{0b@JLEm?DJ(#fon%8}e-$|`y2L=pjFJ4z&34Y6*fkjRUCR4F76 zoi!ptY-d>`Yf#qZd=Z}i;oU}IkY>tc=My|x`}}9zz49?`XB#6#w+u%A5JOsmmQJH*jlf=FK5JW-tG|w=S zdNTA3Du;*~3Amw`gF*gVRKXNIg+6q0f`0z}-Ma(Un0L{V_}Ntw9kKh*{FkDVWc1Q= zGZ*EL94%TW@l}*TvnsZ^V5NfWR%)hefF^o58hl>LkLOcmzg@*rdoK7BoRhDXKQ~Q$ ze?fI{RCFwt!RJjRG3WVNnJ>5576y^$f2!dg-QDH==;ev9n&m<%Eq@@iFIareM|-x| zx!UDV6L=Z5*fF|hL2$&j!%=x3eVhr|1`- zsYy2T=PO2R#pq_{M=0`r&-WBYf9WRf1?@!NGlDEeXFjZeKF>+=<)r9%0`K#eAP4_= z%&L@QMhUhB-MA@AuO<^eO{Z5Oij(<_&>qFve8@vOWIoc=4bx(%7}lEH1gTHw91pT1xM5A?O3U zaU}bgZy{<7+z@)xvXiNxU;Qj)&!Kn<*XTU-kstaOK3E|)^3b1t68k9~%fI%M+iXT1 zNI%S-zdD~ZDCR45gVLG!AuZOpXOQLc*o)nnxB#>KzuZ#E^Y-I^hfYXb0!eul!vtTl-0hTD+w literal 3912 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 diff --git a/files/c/bonuses/03.tar.bz2 b/files/c/bonuses/03.tar.bz2 index 81da2807361d65072c2710f20065885fd5aff759..63b9a4480c7f1c2ebb4d4157240e79c2795a4fbd 100644 GIT binary patch delta 2582 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 sVY+6+141;?Qi?kiER%XfV!Z delta 2608 zcmV-03eWY>6xS3}LRx4!F+o`-Q(3VirmFx4?|+2+xB(D<|NsAg=l=fx|KIum0sshL z4Ssy30000AQj`@cs!#%oRVqM;0l?EuG#VNj85#kQ28MvsMnC`zCLlDCJwty8k|Jp` zlRTn4QTn6EN2ZDCqy{IciIYHR9;Sh&K=lBrA^{i$`qf zRPs+tAhDYzF{x74XL&rV7(B%^Z0#vDrIxUMZ`=Ge?QuDsQ}eyEX6JoOVs!MpBoy3%ltibX1|v;mP~@hn^|?7FnF^%Sc*``f?q3%E5)??wOj;DQmOZV39rd z>UF#Ge{5sp#TrT=5)EMsiv`9^21J zx|#U=*(KYjgW9sk^P2xAD>t~BG>GX_r8?X2r;COxrcOnhG{IVC)^1D{OwI3JjyB}v znkI?Lv2js!RHfQWU96;4GGMs&wpw?%Ox2-jsfs_F6tv@Ola_y&c-p=(`;0|}+c?uZ z%wu8XS#!ctTAd7>xiOwbPK7*E23?kTZH2yfYZn!|XQ|S}_gvY_i>Pdl>0`0wV!BMdhR!mGiB^20}a z>3q02^Qza9-0U!3UaR)LhkhPQciO%;RDL1PEi-p+Z1=Es%33;cWMPb~mnmcFUBUkg z8tfmbCy63a>nNg>id{)^Ts}pj@Tg1_$mv%FD^Fr(FE=G|;A!&-py*&4PK}Cz-7a)y)phWyrkQ;hbQ}V-7)rh6O3JRSnnoKd6@7L2UROd7eKmeJ+!T@a z`;|;3cSFs0j(xq0%UZ0v6)h)ulE!Eb1sE4DQ*?hIL^hv4@8_`HjCc8bxjGrNN^wgM zVw9yS6(ir3?QJvNKMT!oG&T5jUQB&AU7Xg%raxwU^?fFc+G8=6(qhI=GdZx?tCVBq z%S&vWOiY|s#g5GsarHO&1FAeD_0Y}ByDy8^DGfP2OQr6&sYlD5iB_}ZRGTo`_g>P% z?nHm$NPZ%t-lbTyhN>+peO45(AaU|}5V9-V4W5UvT=`SRg$HaWd`lZmUu`~J?9ltl zNm5hVe#C$4?}rb;jP^5e%07AYBF!8>V>kFQX#P$TT{4-qT|SwsrO51J=8?!)sWvx% zG-CfAR}^NA1n%lA-nFI$|7W&n-6mF!5VL=dC}xZN9ZO8KXl*M@nHFJ*f8_ ztUSo)Mp`WVa|x*mcUOt*oZ&YdNERS8ViX?ydek+EXX|?|qMSMYH|kvZoY8bKcFy#8 zN%y1H@}b-!6|SnJt!r`81RY~>#e>Q{L|wehX2%`3lqb6nDOC;Do)4(i8p)Z1^0gf?53@Lj8=q8sDTA>#eI zQF5B4f~b>pNz!0qURDMeuv%SL&R+2^F@F>+y9GtzL5mfcFD)1FYLQaa>%> zg5;TmFb4z(nU*kw3ku3D7gZ@G%1cQaD3OK`Xy+R}9fPopd&L55&TcN)Z3^fd`@jc) zL%WsC-8GVWB|%e&-6?-{ibLOfqdoRgB_=SW?4GX%>p8(y*2Ju9B<|cP` zNRM>@h_+8kG>ban!W2P#D5h-~4?Dd~EVHSxOkxm!@nmaw_wMrb&#MFKaHV;m>Ig$YUzfUF})9 z$0<{3i)RVuix)bTO1zyWOy+NSl#?={%sXJm6roQ*w#|CPcHwQE~!dK`JpIIH5*p^XiEjiCO3& zRF$y6uw0^2jfX~O(^w9rCls0tRQoB9SLL&rIjrg(3mtwa_nMCkt`ec z4Ah}gRGGLFIMq9q7U2vEMe}$x9?6@}$uo$X6A1n@`%P5uYppR;f^bb-%u}SG?ku!( zJx%iIzAV*wMI|12XtPmb(Iu5B?=G^a$D&!moU;_9N|h9%j@1h!-jO*ZFCx5Xpz@bk Sv0+gU{}*yaI8czWBc`j^X5Z=n diff --git a/files/c/bonuses/03.tar.gz b/files/c/bonuses/03.tar.gz index 5e94121548e5c27eb412f52a9c18e8b4adc03aad..360ccf2a21ca4a218e6c9b4f0d550debdebc5633 100644 GIT binary patch delta 2302 zcmV@vO1AwY9TjZf-OYuhH0l**2en`Ghhh5V6n-0Gf4$o0XWaI}^@Nr5pI)v5@VVr2abn8AbK*$Ry08OFa&Qr3z7#nIW|O2z!sjZ;X?e zWYJ(573q3eM1Za`#xX|xEA&yqAzGU*3EbCwIdHzO*16+4WD?tt1xl!B+d`Ei^SFywz9cO zy0qVwns}NGMOsoEuUlNfn%U)P7Mm-|+}r@GVw}B_z{6YtD)I0XG0i=`>BRbf#(f7r zS68bbhvFd9nhF=MA`i}DkSgpWaW&@3K}fXPiU(7zQld=r2kv7lw2wJRHUY`{*IB?7 z<3*z$U-13FA7PF&YeeaNPwr${Lyx&^-B`8?m$N1?vvyV%Tc-0FeGAt8N*SIzWkZgS zC(3H7x)tI%w4V=@=Mko0{s>Qh+ZID9Lp*R}a^@vFs!SFax-8B{VpO!9@IRPv@@>B# zV77^x#jFoaFqQEQ$iy0rT@1}UFLmjS@MN$pMlzWy5~+iTG}RpqhcMzPE3P-(Tg^o2 z1|UC9Z#nNHw4X=v)W8L)}{25cL!W590)yfF9#b4-yOk?V+E zNAx=4*O8!(6m=x2zYybOiKH0$Kj;s_E888K(%CQqIaL24ZXZ%uk zY>>;@?^hBi$RLt&mb1fl8&gyf zFvdLEJ8NqEnd8`^C?oHx*cu$V%$F-Xdm2lV{F&Gz&O}=9QFl{+nC5ibCx0K~!h5QK z6pKA4B&A2q`+^dTFfA9Yh>h>!B(Yb`hAg>}-xIjRo~=bLrGRYwD*s7b*N00#aGigZ z(-=`6QvJ(v{h_5d{B_)ci#D`R&pVlB(t)TA>@?_`zg z<0r`^rw(CuK*u2_oCff+2|5*v+~gRY^S8yZHxWElpRV z@H3{xBR2|)4{ zK0V}PVUG52J}s~p@Ug4>p5uXxxK`!~WJ!S@&WKAiPeVPap@%cF7fj90Ozney>w#-0 zbMaB)_U2`OUXjsj8PZ!q#nD4#k3J*uiAea42!K7yfgTxJx73dUL!3&$$K`bwP`-j? z^i(GaaSTZ^P=>z9`crZ7ppH;btDV$pF@HJYF2k=8j|Q1r-udpkm+Mo#BWpy=IP*DvH*;#2N<2{PmVWxVa&%OazX%-_u4vNRf4a5YLBLCvYvST+ YrXj}r(v$HBB@5i}Kl$@lwE$26049-mnE(I) delta 2303 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 ZYNjE^``VN62qg>B@IMV4Iy3-K003qEl9>Pi diff --git a/files/c/bonuses/04.tar.bz2 b/files/c/bonuses/04.tar.bz2 index 672928966afffd4a474cde102606797ec832f8a2..9cef7aa1633920006c804bf5b67ec61ae3638619 100644 GIT binary patch literal 2527 zcmV<52_W`DT4*^jL0KkKSpai9!vF^0f1LbQQ9)h*|DS*F|L_0*|N1}x0ssI~00>|T z{`=)@K84HN?pxl@x}bIL%JdqQH&|0Ztw13-El zF&b&0&<21200x5~(?HMxqd*vjfJqZgMKwK7MxmqAQ!<`YOn?B|L7)Ht000092_-c> zOqw1@0j7-sqfAYrGz|uT0001J0ThHrg!N3*L}|2`o})pdAOHX~&;S4c27*L{XcIu1 zF$Ba-r8Yq^GJ2RAh9J;r+D1(_NCR`=pD!Px4OFPWR+5njF>pa?zc_l?HS_|csVE}O z=c?;q3TMx+XI&*_>o4R%;*7hec&evtUsu}!!c zjRq4c#E5eSaH?+L6t$8`L_;kg5f<_Q2GRLGtszD8L46!HH$~sM9-Gnu{IG_#%mMY; zv$p@Y&%3|n?Tho4(e<3=1CRQEZm4J>>6146ndIocdK}j&u z<6yE{()ulmA>S5xoYj_931dm{{+ULWW++T8A$(E8NO1?7kxga`hkrdBOwNkeEBWs%olmv^S zO>CZ`xOa$GokT&dEWF{YHCmTN2;@7G*d1d03t)(k<&8? z_3gQXA9Z#F%mWyj8ZtJ{giyO<22v{$iJ#=ta2(VLoF#|yB1c}p9AaSgc?Y` zo_h@dppB%&T+IfGQIXp&S)<;dK*b`L9F4V;PajXe*7sLDWAPyTq3$Dx1KSBWVri3C zSzG*~aS<_F$+fl2W+f656GvCa5BxC7A@EWOWIx3PH%inxYQADGwL(4t6ohAUsChNc)|FaagYh$y$*E$-803QR z!Lq_KqN>?a!CViO`Y&+(YHtRgbF*i~xP{RQRaMWYEo1smIN!~HS`~pct%sw+r*{zg z0Tvb$Ht>xIt|Aw`_-*#k&8o-mop=TeSdFD9mn_RHEle)KLyQppiE<#C;;kb#x7@#4 zvhcg0^rLp1QKXD@2XEEbW{m>xgE3y7q{<_$@(Ug^PgedZ*LFUoTQl1f5I)&22+0_0&5)CUX#my~GoqC9(JD9|Akh$*N-{P7+ zri{u5DmOT%l4?pG9#^AiNRre_5}R#moh83bDpUAKz-yMZ~nkn1(|@W{-RVj26!bkp)T^nqZzG{7V(fB}s3!1{E0robgy>glO60Fjl{~QR>Lq zy)tP1gYuJ~8N8Zulo3ay7fIow8BnB`$Sw9ME?mX}su{>5?DKm-)uQ_R@GWCKIOisZ zsod5;k$UG^Rz?Ss)KN|iM#^R#;Yg~&T=P&y&?E2AUvM&YF<<4Gv1eb<^k-j@6RVym z%t6Pizd--Q!d?Psz^scOs6CeuB})iF6SdT3NE?Xoy{u*g0)-X& z3*_?Z6@vqor)u5WuPC7F(qeefSvPksy$=q_MsEv4l(RCkI3gl5_e?6l^T<<5&a@T| zYHtf|@OW#gs7J90m_h}h=SMJY5*X6uln!E>Z3jZtf#CH;hd)_}<$4RpfpZ|~z(~kM zm4_Q76hja@JJ_A(8GCU+KW0s;4_TsKay&}<+TJWFy^Y#R3RU)o25ZWO7NJ)hr}0xr znu$7GdrkS+A&mt7!byl@`cMNnkGgl zV*?tc%5x)_3{pnVWL!Rhs+J{)(BEMCWz{8`1$w}hm7t`N)Qq5==(N0=;4DBYw6L)B zC>Jf_Jk1+28MzzAfcS)sq3)e|_3BZ$7Hbm*^zr<5IsD!k*9=zD%}C)qq(m?d80ADn z3KDX06(C5(lp=(PIE4!mThqz|uY(dXH><+rOuK6A$jG&I-Nn-?gN_eF6lAbPqjCT5rxMGpx9@2yS`uJnOCs>PhR*3vc!C6$ohAs9bqfa= z3>s-MHpVHU!r@|U%4A#8FyLuPr$*MQqY#+kmU&IhISNrQ>&>`WH&W9Lg=O^3HX{L9 zxSGWa@X33|V~ZZ2CvU!meEIE$gmZ9@P<`(9jbIZ-_Tm6I8{rZyOuOA-!P;ZlvXlx^ p>ZPDIi=H8YcNT9d1fo2$d{Tnd&^lw5K#+gM+>uTcBmf-GFu*DalpFv6 literal 2531 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 diff --git a/files/c/bonuses/04.tar.gz b/files/c/bonuses/04.tar.gz index 197ef1b238c5f34ced8e6d7b84c58d7b4e33acef..b0729ff216ab8d2626ceb808076b56e3b30d3f89 100644 GIT binary patch literal 2500 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 OD*Ol66cKU&Pyhf}zvwam literal 2499 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 Cpu@ue literal 3632 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 CE4|SG diff --git a/files/c/bonuses/05-06.tar.gz b/files/c/bonuses/05-06.tar.gz index eae5bc9da6f45c4e01fa66a3ee0bc77a328a491d..c6da8f7a622b8e8debb3942d89b525da9f5999c6 100644 GIT binary patch delta 3344 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 af(k0Apn?i2sGx$r9r`~J3LaAccmM#)o2qC4 delta 3344 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 a1r=0KK?N05P(cNKJM@2uPF+|4cmM!^0g^)i diff --git a/files/c/bonuses/08.tar.bz2 b/files/c/bonuses/08.tar.bz2 index 3274d27b4c2fed506ccaf7f2d802996fb0b21646..7a9fc03ea941740db113e8633473076416c7bca3 100644 GIT binary patch literal 74418 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≷W*Rm{t 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 Ez*!c`SpWb4 literal 73707 zcmcG#bx<5Z*YLZGF0jDjiv||=MT6_&65KtwyOZE78azON;0{582ZB2U5AN;>1dUvt z_qq3eb*pZD|9xH6GgH&ur_VWEHK%9J{A7&mg?Xe6nY0aiLL0UKD8m0D*Xn@)vw#0K z-(LQk`uFeOUjPaKWP$Nk{3UPbk^ulEJS>$_yk!0cmm+$O;U>SZV5R^UBUD@pa1#m` zrJz@%uvgRUQd2{fvK|SPMot5h0phgwLcF*XfYCC#vIyD%cvu0yl@&h#fEc3%0PLp$ z0F2P*GXU`a+lc`QQq7UihRaIL#vWH5Ia=G_R-QN)&-xcWrb)R_YX1(~-FhQ=Z9;b! zQk6#AqtT2jP<3CjH&`Xv2WCL4VGu8zh%n_g4R{$t`%lZnFE3)2*|NrTLv)Jk4mL3FXi8-+}y=Q>yUJ2MN_x zXM5i`x<|Zit9TB@zq~xUJpd24jUscLb?zki_PyFAyS3G?? zvc!Eam~+%Bkwp-dW_Qe11xo%kSA!lHcN5WP^v#z5ec-R)zf|J?S~M>U&^6rMsqm9= zEhHr_Uo|!TeAG+(7LMa-|F^q9QkY7$^3%g13M&{xtyPjivJBEaLM)7(8RnDLl~Ek~ z&xS^r(4B@H-i)?|wo;&ol9}va!JLB?MqW>7UGz)kW)4_(LIX@ z1U1r=ythq)CsO4S&==aS27Ic-QAd{>EE5sxBX}VaJN=ey!U2O= zRfC(4Q_%O>ZJ8%_8 zbpX0swNR#`9;ejuLvdt~QpLPyL_MQwNSflYAhp}3mlyX=zlB}MWO1ZEQZ8a*@7-OOm&G%A$mvW?>Q4m6Nnt4qo zd}R3Qjeg#DJYSA&BsgjBDE)^7U`;!^;VhzEd4W zB=G>V`RL^q3hn$}Qm5>4;wJ0){rN(#^&=r*vQv#Rr4&x!l4o1DV2(;D(f-_0Ujb*+i zoWcDZe{&BZdFKX&Eg`b)3WI*2i!wY9Z;Ip3iuQ9nLeVe?) z%giMg-UypA!UcZGTA2s4n9&5+eQC9nIOOR`wKpr-lFCg-K_IsDwbOEZXLa^6@G{S# zHh1V2Xiwo-931t|S*+L@M#LjjQ&B>s4=*{t3_(^Xhxkx_pC1YFC*!OacoyguIs~?} zl@5Ff0dox2@D^G1Wq-GgmvPR$Ii|R4J8k8_f>3pAwSFC>Lj9SLG-T|VKL<%wII;?F zR4r?KILUj&SRX zgaW0ruoZVQ5DLUqFv0XHm{6%EL8Dd$@|u_=)kYxCfA@IZl}Kk!6P?uvL0sw^7YPf9!ye_$nIfv~5yE0_ z0|NmdDIfqP0?t%fZuBf~r3hQAgAEdUz{1Wj=EPd5;hQP43nxE%y zf37qCuT=aEF9KB8-Tx&OZGrzke)*4vMTMaJ|E|e(prILR`{i>S7oeAFcs~96_V3U0 z@ut84i3A}*pl1U?v;aJKPtwzTjY@pT@&r2SVt7ocwu&EMu9koLG#NE>!W*^VXs!v! ztoia?OZP@nUDku6@cIOeiC>30;F>|2nX~Gk-i+%(|jwL^LAq zv@6daU1w-zrPgH$>|=ogUCC+ycO`8pK{Z;Wb*@DPTb7G_^HxUd*rd+RR1hLlO5wCE zjW?57%J#7ZDAoi;vh(?AGZnY7uQYHmvH>J&w2`!s*iuR5z?htH zn%Lx#{|pBwNI^qUPh?(I-~3A?(ba>|#+j!Q`Y%yN#u4KH2GF%f4}bQLpNuu1zZJ_d z2M6DA8fxkh+A|yw3S$Yi8qalEnjG@1`}lQE)q>hXF~dk%AfYApbXc?%e|b?p!|4g> zArD<{1-~qRw|xHb1{|O+G3m0;-4U>V@x(;YDxPFHSS9vx zq>LaUA# zhFAA6hKY?~S7;NDb&u+g#nyWhhdeg{tS)7Sf3+M0z}K4x>`%;72a?>oj=#Uk-+lOJ zcAX?CU>BcbbU!cmAu;#rD0fca&F~BFMWfSepZ7+8KF#vk$41>2t~cyz2f%;+)uXJT zvTU9d-m$!^c50wnZ<{fzaU3DS72$X(r;~MwgWjW~()Oa9{X#67{B!rDBM+|7&Sua{ z!i>+rAN$`|v%OHc7z%t%_!^m+yMLIyd1Ij6fjcX?e0Cn?9Vt`ta^;$|*^S%F=e*$- zF%WDVd5bg=<-WAr7C-&afbsV=Vm0c#Ka|NCD0r;wgif_S?dVjg5>Vb1jI(G{CL^hg zAMulzD;Y)c$6+BChyPyUIl%%}02Ruowk(lzN{t5hDp20P$! z$j%|fR(-XkQNJ!>6d|(H@Awk0tzUSgS?qz~(a_g0iEHb0r;J(BcS|9yo^pZE1co3A z=-$zCjcw5@m)-@_i;wRJ$H%mWt89Eb&e0{)w;u?Umr6%p3?>AAm0tT5Ybs!*3ZZql zA!12Q7||G3NI|omoBLWiu@^5|g!9o0QAdWX2ghSk(ZXw;e+OIP4mMk~&8gku+YDm0 z;Km@DGFP1>);9CtCR;>O(-*krPO)CO~??bZq+JH-So z-1iEhcr!mvp6;z;?j6-TKKz#8{NNQAWnJ4+CMIV8Gl)X#J*;Gs>perc8 z@U(#ou!Bvv>A&R zLbmM@X#&M;O^YYL_FFe@StApgKO-v}|Irp)vP?U5sAQ1c#Isw6i*qnius-B zLUB&*pZ8yf+}@b}!*xwSKH!sF&TqyHj;~7+IvBdN-j|}y<@G^2rY`^H7VLPKQ-Yem~lmO78GWf?Q0FI$vW%pNrVd8 zkL;7aCY`Iu|C~T(Wq0u`kq^P?foVtd&WLCLXDL*e*x*=#(d~KsD1CEhubD;F2s1 zV+hVV-=E@r0SpIHkqa}lX&g-T#z^AkG_vv2CB~*(&b{|-Ha(c3)XO$zf*Qx*b_l0@ zLxl)?J^P*0W5K!$tRvkZ+px8_)fC|_ak^MMk^ovt!W)A7x)WO`Ftn{kCtu5@WX<$D z3mb!J#@%PdRP3*atyb?nbGRjz4a5$|5}Wo?x`=CgXNuo*Ggp7-#uaqGb>Ba_u{8O@ zaU!Bnor#=srA{Z4@O_J?#@t%H0QQ?h87|-d;9X0Ij5Kxqix+``DV8lplJn<9V)A

    UJQh$-8*ZGiWO&0yTSj+CGVU_%*n8(wJQA>_(A|*7FB>v7~&p z2UW$$mx!3+@}~Y6E-Dduz5e$cpIet6c*kGb=ok5j9-Rda4;O0QvubmiCr0}$ioI86 zZ9M&$YxHL~Q+-LIJafnGyOl)1PdECk7aA8FLt&i!ufd>6N_>?2dbr=h{F*rx+;~M0d-08y}P&F zS546$t4$FlO$?}2*F~W1O{|DQ%F4x8L`>)k-oLpSb%c5AciDAyerW~3y)_P){_K<<55nO$@XU{8&Vm2!n$Bn8@Z?);6SixaphjKJRjizM1dp zf=k|t(MHSI$tuBsShc;^j=hY8do(Ye#-F29dOJC%7DCuZCW{DYn_~hWDHgMuoV_zxS9M&?=>$E=2x??9NA-!LHbPGuhWD4DL-m1 z>mpLPos=_!*KX*G_FL%b@Me#v@I4Pk;U@A4C7E@%jUF}GImbmr2HxPa1C^8_o+*-= z-GYCDW_$QyXP1uq#zgkzr3-?mZmh#!PCvSi&n|Br(ops{MDhwr^)F;*UuFjF^$mZ8 z%*?6}vXPzS8wL4!aVO^cojQ1bN#M{p*R;vYTs2yAZ4;?~xsnxn-R$u(E(?aM_N!VFs_ zfwb4mbs}HcG%>(BlSEsdx5`!o?Am_elygxFWA7>u)q+;2g1+ zjK@mf***EWVzZSHZR?9}=Rw=f`X*M5NI@%gG?R!l#$lE#%^3{rd$oVWvy)evISj~; zxSsJ!%qbID&@c*4d3-CGUzv+0T}F|x<)=TNhF+d0J~6dl4hCFZU$#2)mmrN)WlVE7 zc+PV*^_1>#I1}LOL3jQHL3-UoG&4IncRS@xq}L8#Ad*-e@V4(c^gDz27o{1Dx)JeL^VfuFoK={9}Kbt7{aEHj>a ziZEq?B<$vm7p>Kwb$PD8$KAeEPg7zvZPZT9o!H0XXj#R%o!wPZ|3)N#EjBT!5^>a$ zjZm0$x;b{~iudWFfjwrPzf;fg924>h7WZv6>mXxKpO1|!$?gBTAHXiY-E`ZHV0>-X z9x+Vs(Mz$Cv>0Pva5?lc5mx-djXU+`IJkb1&T-b;{xO}LWtV2Dj-QfWNco07voctDW7s|hfVxOx|);GAz9HUry9r7Dn5$fISyEJg@KK= zO%8@#$#*X?SHWN9BZIOdb6HqA?8?#Bv5wvw*YPa@PkuvJB}-4K^5`ED=e>NyZ2V`~ zh1AP1BA}Le2V6;ePU9fQzQt&Q-bMx58+a^3K9))I06(}{R&aZ_+`H(UV|u-}|3F@M z1sZs5x$eaoWn=UQtE)7pCdJ$=ALb~Ak%-50CARkjPLK%4##8i+Bu_Gv9@$h2tg2H> z3DoamFt$1HC#LFohdwH(sSvTF)PRKEb7BvW8@y%5+|NGEHYfoZ4uqr5LX)!BMyLj5|S3hdn@(=G0~|Z zLP;4H_Jv5uFnxLq)v~-2?Q7@8@iGG!>b%TImoZc0x~GoS%q1f%f(Ufnj=Q_d3+qJd z`=I-8rrPR9e-$d<3i}bYy6{~ZyE`oNu8rm*H*$ut=h$~@la}9${|Wkr827gNd>15l z?NugD>7j8vD}8 z^5Qu4T{jb{xJ^0#O!XpNF*-kY-=?XPf2|d(>-}Hxf)n)qhFTuBMeX;0--x}jdkg7& z!kE1HrdP9_Vs{A7AEI&Q@A-|keL7j*F^?Ec&_>b+^}ehwowb^%iryCN+I+v^rn;P! zuig575&VK=eQpU*{_XeEW3^b_uRFQCGrw$%*GYc;C_i!^g2aony>bp1N2yF8CU%TJ zs<y zAednssad=6woAQjUZBF2(`>k#H2M_b0k-1CD#l%Pr8}x3t9j2>n<>Pr(FYgmZ74T; zz_%*?W@LHjL-qcZN=WCYxvf^|>@@zp4=q}F33)BTibEHom#aY@xmRi`Y2yjRDUGF` z(}u5w;ttexswWXzRCasTm+zy{J|z5=Bx<1k$TQq&bN4lXXAK8j897|yG_4Jt=e{^ z1L-?KZ7~1#b~t?}3l+ao<1QK8eny4DzHRS$^H+?>yyQBQiu&?b*sZuBu^~rz96X5; z>CfzgDZ{aFsJ*+1cYGXR7a-u*;A-fB%$RO-HTh#3Xz=sM6?JORHFM&d%AyhKj~B?f z-JsuSd|bp5G`|F6>f=#|Pb7-CKX#q!*H@(7N8q3T&_gK-88Cl){rjKf`R}iE>rZCi z=O1_;etLda;~%H;YzcaY0KUOv>GIJs)QV=L1tEYwNm5dfgajZ+o^wO-H~V!roeQac z2?s4@47*_O*nv{s&OeoJPv&Xw6oAOvju z^374iY`OdQl;|BpZc+$et6PwM;E3YgahsBh%lT)0%g9!oMJQ}8)7uDr*V<&p9=Uvo zB|TyGXH@ZiskxX7$EZ(_(+&C~P$8nMxy+cre&28zurgr!IFt2h=k9cU_icADbFKJh z!@X3)(?=V(yH9RiZ#U*I3h{TZ841x-X&!?k|GpgxR=Sn2`}t;?f)wXP%)wiJz?&^{ zt9uk6(aNv|=BUSXsGUujE$*3Og2JtF_hC0FQ+Z`{7J2xFC2kIiu@E6kA2V3372X5N zN+CM<{kyEpHVu1nbbBOu@`q9{-F$;n6*jK?4jQ=csEU5GFbI-3LStkbg&TwH2Y#X^ z9TOxy3HxB+QEJ=&ykPbjIefy&?}mLs9*g6E~V#^L7mn{P?NwMc#MLJ%@iS6}ysi0apq4m&$9 zcH58UoO1$>0Weys5%%Hw!923BS$Y@MZI7A-%~E}X&Oy8vp{l+pV>&4N)&9n>Ed-Cg zUKy`#9fOTu^Ymvk$xHQ7P$M?8P(5B4z0Q`^)c#65`XjBTjq@`W#m&Xun|c9T?zT6q zp>+mPdsJ0{C_HeME&q$f%urp4@Uu9=skxLR)iAi5EEev7sjk_=T6QX-H3Q>^=&cDa zC-7%R*~%k~0xHbphPSq(T7lZXc{NF3pzx|*P3CtsuM&RX*ME2;n}&`$oQ=4v3hD@C2CCSWV?JbLXJ$JJB!@BGJwwLhTNy32w3V z>ig5J^QW;gZ1pl(M^miom}MW8kTDafRg-f{f2Nmi_qvb`HbYx%I3}Ec5h9Kwm@<*d z6L!}B9%m1uDWA_QG1J|9z7lR0M<$xy{k8K*vfAt~8?9)j9>+mS3M})hD2`&_&ER*JG<8Cu%X)+X4;qqM79E}N_PBlSl4&Gzm z-9aBdjQt=Er!A_!>Sf?&$M^2qjV3n2di|AcsR*U2DloJ8mB6RGX%bys;d?kDxZX_4 z#NQjovux%yhzL1I9dya__y-en+W~IEx@5{~_%Za89DfgiZbd79)zt-Z?$Bm~)gzo6 zc+p;Dj~UzJd>P5hq8vpS$FlDWZTif>Qzio)jm>4wl(L?6ok~kzQe=`7I z4O&%iY2`P--OHe6Xc+?6YEa8cK|>?DykBWJmPN=9@aY^PO=HV|adzGMptiLD>)_ge zg`QKIdCB?uALEoF!>%xT5IRU58IlEfd1D6~c~R%9bVZ$zq)jg2yyIiOQ;5bD0g!e<=|pQ4$_kP5cjcZwb`aH#Oe}8BYDeIY^tVo=OdcVT}Qor;eczyNpjOx<&>h(-3)OF3x!pt?KQDrS*EN!8ZQFyTCu@ecihI+ zhII?*XpFLy9u8w8P>e}UU`@}L2opt#>@Q$IAkcCL#c!%|i^X{{L^;U|@3kCytUJn4 zu}5+FS}1xNnG)9viyIoyMu#dRaN8!x*;Uy3gbZf4l{JM36S6ewnNc+QBe+O=*Rjbn zShLYF6&-le2xEz(Bb%aSBQ)w4IJj^_8)2A)A~HHYUwF`I&l+0=9inxu*>ORUFc`cp zZaOZ1$rbJ6n{Px(3Vac!k0#e+8ZH!6Ye6?mbk+;Xq2z2Q2gF#Bs00^LFBMr+JM(?d z`TMl=Xf#}Y;8w}K3HDW&S4^1?IXu^@hUFV`w>E=G*phxK+J1i}L#3#IS`SJgfXL1g zI#zCx+TIteP^h{M?ES zXqpYsHK6xgkUU_8=;g?okgLYnTbwLdv-Iyk$ynUw;u@KRkP zkDW{pvd9@b$L2(pk_55LLjByQE$^5VCTs4+ewL4Ob4oEj##u=3Y_cUl>`lVZigd9miB`Y56kGB0q}q&{lbZ&LJCKwZfz1<9`Ug`DCEJkx(ip^|Gs$X6BBE* zplcH6*{%LIGTho044tfn(sIZeGDVxT=}?viU}&u}gCk`#83j)qsIYZ|n)j zA!F%gNk|nYt*&|a78ujlv?pNyHfXSX-W*!U)p*D9{)@)wuqahsl`KO;hV@E#?#j9o zWxXtA^d5SnB_TCK%1M7SBZ)jqdMN^f7gwsL(x5>nMLHp-y{@rQ8CFzP3ZXsoBQO7O zRa8VkGGlmL)noKg(l;yce6A6XAevm3rQhCmQky|$+=w1(9Mw3h`+1xs(t%*I-i6G# zqOxRbPUz=poPsD69PmTMKFb>lvHYfQd~)t4~@6LL6*-8^Y>bMePtR$1L0hhHX3Dj7DB#3ZjOZ)+9WSQr-tea#pPw6QVLsEnh26_pv3 zR5$hbGb-+mF$>GX{v_AIh^tgcOSlq==rl}DkBWW>)+$e+GduI5MhkBa_yu~G9fu~d z+U7zRiNTPOTF4+DfQ*djOULP1k}zX+t%sFWj$42%(IOZUpwx)SH;HHAIif>@It290 zUj&WyE9_%fbC4Vb!2^-sik=f^Y+21!0tTaEId0}SJb0Coa3KH#eFd?^x==_IV=|F26!mg=|CTk5 zpw$Ml)7>f3$$Bk^9gwbD<4Z~8_b_N?;%Q;%XwgHOd7zs8P zgGuA!CEPk1A4fq+dew?|*SfxS>ZdT;z>G3S?F{{0U30p9d8)XTZh}&y#pV@QO}w#- zq(|*0ZpiZG&`xTDk#4}yNw%R8hdFN>1=Y)yONvk#kRmU-tcCaoCm(bzE~%3`59&UX z#d+|&w^*{-QHu!{9Tssi5lxv$SQ#Ki)?txqoQA~fB|vPXlI3DW`1SHzSbm=Vx0&m} zA{Z-)MkH3UqX$O#U$8n?XyR0cSx55C-)IpMrWjRnML>v=%EpJFLb+kW#Oz=; zH*z1?iT{TlVC>vt+|FzZL1(u5B~+P|GuUPGq@)m3xmsp}!^+QVCr9Un8B}~2{g~M^ z9MmJhGklnb9_R~!vjy#*`x{OP_BC#1wjCxib40mpIt~q}67O(J3#7-PUhP&a~*i9KO= zacAlKzDj0OQ~AjcuTn*c8aOiY^~<9(2c4MojV+@cnHKw&Y+9)7I4O)(>4o6^3ES*@ z&5MSg9Wo7D8BE)3zSK5?WXIG#rk9UE$_Gty&4o(x=rD|Deq;j6;; z@FDYC+MA790XSM*hzeEH7T@)qyDNUpUb%&G%VhSGal(D@kw&8?t6CP+5>Z%tiebrG zv^U4kz-4%FFkTz(-tKMtt1;aQL<@=|1clQ^%A(dkRw_xKDq7IH(z^>;lcXH7oQI`^ zX+xt~+Ib*IxW-yb0IIH({A)@?(Dg>gUM9gseW547g1>I*O&KOpcrChP(u2n)NyOn@ zuE&911Xa`1c#ngR`p{^ftD^UhJLA>lN64PEV$pN-l80&PdEOZnjT_oG8#);hAbzIJ zP4uMoG`(lh1b&W^rh%%*%JODJYalD)kdZI~5G`khU(^r;1dr5+$07`Ma~^FLDd+vD zJm{}P?XfUzNdPN9_-N*xvZRq0?rCB1&O0}xJ+wV*~?i)}@N>syIXT~jUJ z2bCVoW%3tZT$+odQeW+gCtRG`4p{*QKzejw%k+M5I^iG-T{P4p1+CH|f-sgfY8c28 zD~r|(ktXsMOp3E#myVaqV#y@0f}*lnWNT?HJFzgz#L1^yr1#75Un0t6Z3lWG0|hDA zbT*KJt#B<(7DIV>Utcsx`#GUp%9>^2q|8*f^TNH4*bWPICV-J?1Q+i}5eVx8z7s7l zsgjm};=D^>>UU6b*I8Q@+y0`e!f#p?Y4zIKZvc}haoxf-$umQ3BTs}pikKL|Y5!TA zy+2c>l)a6!gX_BzR9P@(w?j0fI`oA?dqi=wSpyic#sN&L@W0m7SLZ;M=hU*rT+yb? zQluJp=5G1*olM2@@ui;-IwI7^{{M_f1ez zjI#Sr2}Z}c&V1I1@*d1qwit4Dt<33^Rq5nxEUu!Q@O3nyj>hfh60+}L$%%^wtnepV zX=UVCz*Hb*q(xeD+l|{!jWYx;Oio65wYsa)2x8qgAQDJ3arsHO{!x(}LRVLHVA{c( z4ipLPiKGL`u0~!#bFhzB*xGSgdk+Vmel%I7hqMnl=P2js=3xx=Op!ZX^7YA#g19;qmKG9~mxgR#i0f^TiZWnhgb7-YZ$1UW2Lz98i_<3S z{W34!>VDkrJD8#bMAe}C#GCy-)gmhfO3H_&Y^4bT}4KEYnnreO)_Xn-0vD5=x?X$h)(d%Y$wx- zTw}JSx8bm~nQ6%q<@C43={yW^>6I2EYph9xM0$rcygmutpEm5i8p1bg+UdrOQ** zKiNU{%`us|r2v!Ss0!7Kk<;ib9_quCUbS4}w%Ef>`IuKyM5z<-a4a%s+MVX+JV@%je9I#hj0`ANK6%D#ka-UG70{c)iv*@GkCZO{LHTr zF%4Gy5VMub%}O|p;!3!+WV(ZgYDN11lAwA?tPm0x!-tXja2+I8}b{H@!cNrN1Z-OOC6Y#2^jV3Nf@RzozdQvWWres$2 z^h}PzIt)R40bQ!;_?NnZVMhtdSPxdmvv{QfLob+uH&d}slTP;2K)eTaZQ5hRJqpX} zb7$;S9f3T$t4&0uOR+FxZ-xO4jUt}LZF0}ix7caur`KG2P=$c$FPFMjW>H%UxHL-(K6@)0IZ6L&%jx701B$tRrKvToG#oRqY zA?1KVso5~Ic)()KnoBB(iQhr()P)~P14&I+#6=TRWdXx@_gzp^EZjU2(7vdkhZhYP zqPJH_5^@1D+EjC8Vc7G@%CUsEA4L9|FrPMjYnK4|+5E7wsg;&&mvw+A1P(Z^8&!=P zaiV-S?8~KAjKz;P++W@xTP{F%$xr`zn1Cx zvKq{_->$Gwpu9g}iBC|4lk&B5mYXUa2~=iAF$}DDyFv>&gHNaLcW(R$!=%Emz{qxw z2$ydVN#)o9^RBE#E?GJn43>0moCkcT^o6;@c+!=WVzef5>Su$Ega(T!6)1hWt=(NH z`*~V2Dn1(m_msi7Y!ogWyhaxWAKFI%q!rZr)5MA{**S3$?@Ki~U@|BCUr+i#bjhNK;_3 zh`c%Z(oW~OY+;h$8wP#seM{6~jN>T@VgW~LZ44!z}-3DT0yMW;Z=s@D~Ct8n#g=GVp~zP6HO z<|KJVS?OKZNG^x5^V50|cTZx;dSexXMzOpP@)GfK0j)xe-R>QOt`Qvw0fWRD5;dRA z=g6g7YShqzq;UzOBH{AZSZM-pI#Dmp_-PW4eRyC=woZZrP6lP3x)QO{OBd^Gb=4@6 zyy744R)fmFD@Re@==)pYp4Do1f~~r`XW!{$C&xi(vbDqoNt;6FgW`C5NQLu3k#aKZ zz>ADiMH=r<@|}LC`zxO$GaEGY$Z!QM;ltZxzT_-rue@b!t1~(5h%KcWAmKKO`sX~{ znOqtJIgOkuq=pkFYeT1U4R;n%K|C_XbBI*hUJeP8a|ZJuZdW4{8>(g@JxzAO{pjUv zN6t8pdmp_q+SCNFAOfCXd~!U*x4SHF)YIE{>Ghq%AZ!`% zPoNhb$59@&Z&^|oNCVrK8@=JwD^}J0Y(E(DB}@#WS)CmQ8x|h6Zv^MyS7NL-V4<}F6D#EqQqWo{!gZBD2r(qNy_e&|Q(I4fYei2i zt5MQB3-*lqSX7Q@+L{SV@d z<*1I_FJ1XQW1Ao$VUuj|xe6$aJTz`nTPio#y(zXf;D@=mUYkvlWp?K8OrP(RsR4an zc%&&ND9SbMO?y5x+>F)-_gqp>b5y&AZO|-LKI*nuU<7(86p}Myt)d&E zS!*&#kwesexCF^3RT?6{O2hk(mMIJzNzI@bOZEi(AKUe(^^3b4!n@4K`ZK(dNrhYs zhWn@1-FJ19;?tK5xeVR?K`sr1vtjEjt8!RI+pKUOPcqr=iwjGH9^6>WSIxc|xg3d|XoK#yj`#tvn$ z-bU&Ki?!<_erlg25uhfD29lT@|C)R!-mv_t&LUOL)}(tYh*K4VU~bZQ3<8pYfRGiD zyj8cK=7t2A5;G%V8B}0mX##RIC_T0d2Wp#A7BEur`7iq91z^r+!;>t?9r>pFpGc}` zRuG(S85>Fk;CfM?RIW`f6?H!+Fl9lx5B?SrXtx)uyf(kCoajyi$Ecq$)PH2iO?G=mRzLtW={K%3O`O$8IHUk6|DohlGiM#e5$-<7Emn{i%m-}8S304;F&A! z@i2CDOz^gc9tl)pO>Qi?1-2vY+foemRR@m3x-c%T{B4W`S~gwDNmE4CABcj!$Hnv$ zC6%$*0M~#ML~DYInm=L+&1)z#?!G>t{uuz;zq>siIOqH}B?zIUKZSx+fIS2NZzn&=EaTI>P_M-;A@`O5aoZ zK|w$O762HD;>iEpiX92_`XAUQSGo`-i~P(f((&jgLyv+(~yIUJ?gm|HGu z7PM#p1^@;GtKwNB)n{a9LPJj}ebECWl1pl}tw#z3Py~Q!i8P~R2>v7dznD&AruB>e zU^<}?Kr#R-#Z>&P5xhc%`TwxF-=q`PMsPM`{zKjT?+aT0J>Z2js%74#`}d$%U3cBD zSE(MnLb|S}B3f6S120iWJyEgs41a-O+8LztqZHRU)Ujc5v z(HwS8@t@Xxaw2JMpW7JjvNI35cxsh+yra2m4+*_j|MkB6_V&`$Z!P35=v#~Erq5mX z=f{JG%dU-I-QPFenuERt^WJug-G)$Y`m6`#?mK-C`V@4Y{-wL_*ZPJ1opI+y(80#V z)Txv2xys9s1G8nn)~2qrU#o{=>sbLS3PE)bz(FGMbvKVM0d1E--M`jPgT!$R0`5A` zjXS4=m((H-mwZ3zo3-C<;$Cko-}(hKt^0a+^V~c+PX21V`{dWXX*BoK7vIY_9%*LW0tA%q zHvPL6?z~o>I{lo?eJ_32FRNGT1b%hVJhcY-eR;g>@_m}R>ngXCn`=2(oqD?L?z%Z` zIX!hfT+M&#KFBI{>RSJGZFuL#-ukKK*Lm@&(dwz6Q|-=;lSAI=RCmbW5BM$3uZyRU z+m_3&OPWp7mR0||O}~cK)Z2%a3)k+T)j89y%dU_XzwW!vxUx{D2&w;INdN#4jyBK> z1)$Ag6|169@bbgeh(-qHq$6iiQp%W!uyOzZCIF}hkQ1d%$HV_078-!{e2_;Q^Z(BU z5fPI;TF>)MRRG$^0Ix$CL79BmD_-mAkpX^QjVfyta5QMd9zX<8RekQ`P*^a?zXB{E z$4FG2p@1?)M^0kMtEO3xSW#q6j|K40DMcV|h<{6`4@LeG=jEp;)ERjuq(Z0d;b_(a z7&#R7_5jd8ABGf>^=KMa8dHLNPQFZ_y+b&!1D`xoj$r?e#sxg9!CY7{fGRbeU65Te&}ZE)_v)mnZ51h)nEW$~MD{aC$Z-V*r5y2F%cg0&hj}E8gH466=$NKd)<| z@C4MG^fN&gY~JC|D8MS@C)Nw4a0?5Om(sXRRY3lG5RQPo$O0EEAxm%l&iVDNWdK%o zw4l81jFa`4z6F(U8iy&y%uuK9$L0Tw=kjg{FF0m6$EN}PlTwj00DGg=Yhky>9bvY zWOAqDUO>yOA8r~amzL1`n(xe5!X~*A;V&0C@F*73eF9#Qix$!Px;`A=RIK?X9u8tW zqF6`#1IN^T^0v_)n~2=niU^KnDH^=S`A(IS71Nm0I{K%}=)j6+;g|s-XTj^=@>Npm znwx-2KjuN9?WOH`M1H{UK;5tq+cvGL6JMIr*a%r3mj;#&?2gq$Q5%y1Hfw||)hc7j zPu7LSx-dB2kM&m-f9_04JvaS4S~wqD`Fgvo{*@ZcQ)Y+S8cy4YKG8A1Y?M{Wx%&7E zi$5iT2~#^k5KN+DT6>qMzfx)YkvhbDXwv`)tevMNCM|xp~GGL*lV{7P6_^z zs1)nAuDd2m`S{a5iMu4isIRYkBn13ktYGpYF z=PKDroG}<>^GukS3|lHn#84(~f8a7GklGnwO${KfCG8B}98k$_#mIDRWi>#;V(_t} zLsyqE)roaQ`RsBCK=8;nNvNc)v*a%s&yfCSQaYL|sA7NtLMV4lW;pjY5uGy zTA7fTXYEFfBLt{~!TuF0M;(kyv4t2qCNJ$n3F|^RM*=r?LxWKUN*$2NFsSTdAyBgw z;bXoaAl6{L`9@5aEdseLvC&wGOWb!dhU?_d*P(a8@8K4q|03p>~UQLb{AFH{25Si8Z7b`wpPo&-WZP9dZ!=>I!$=F`+ zt==^a2MV(inm?PMcRLwk0k(2MI~`dH>-r3#Drg4gL}D)65?7MT!x=QrYhFkU2mwaL zf@KlL=uz6;TS0M^_Wk z<6V;3a1~$Cwo938cn$L+~?Wud0!=uK~1q#b#K9+cp08@2+j!k0j zztMnZO!aX6YKsV<#Up`}&B4@v`X}OSMY{6{GTIJ!3`v8*rUj+M^<>*EXyDY97V$^w z;Hz`)jWPQBy0mAMbv$`|gjTfx-Cse${3^ZUYsrRB>7VFQzLHF=iNTE}nv{ zXj2#=z^8okxqe3MKnCN?IYXYh(w|O{3ZZ5zfLHMe!MC`|qLlwD!@VU{aLC8^go>0# zCzTu;wpLk4YDb;go}jfcPPc9`^gL1xv@tBHEU*m3VYfG@2r$}MQ2%+Ks>GL{;XiUU zJiiA;VBSO&#UzKOn{aekHeg9Mq8z^ zPdneP^vT-;l;9r#ww_sOHq(W!@gE(y3KT{&dM%v>ExCmi{ri<~@EmXOiPq@fPQ)u9 z24H#aZRz8>VNpQ$#S33V?v~Zhob{W|a@^=KrcT*WHPWs+-`EMx_oG!qIdS6KTa7H> z_3E$7D!i`-QQqOnfIbx7JU^VfIzaCtvK+_aDP;e9qhe4R?o5BEfmI5_rpnJqGuL^8DH1xNX!yJ z83jm7>~Rqt5$QtoZP@5iLhM>@b0~<6R0sA}FgT5={B%`$d1eYy;+a>uxF__(xo?8d z#N3kUG^(MgSImee03WwD%hQu7cEQ?zvt&P1-=wW(f0UFQ-Xj#T>*6-AW5{SxO6ZRk zm!h`RX8+n6_N1eU66|k!)@}+gn5sx-zCW*cNhAWS9lTm8M6HwJs8x9 z6S0xfMCtZ^f?u5Gy5^zxSdia3814op+Gw^$=$m)hO;}8}7DfYU$ya@~sXi$U2jtv_ zu4!0%;G)TSRJZ#$6#QZ&`_rR-SdE^Jr`8dcYD>p_R|FUyT0U9&`v)Zq$XCr2gNUaJ zb$H!WV+5-Ulra|vW_xMK3{wA=a%~;%90UlMp%C(Xa7GJn$4T8AmS$8h&EHqCZ7hsx zfV1@5SK7spUe0Lv`&x)X;2%*M>#%Z^Otb#HH6xy&KkeR?gtgKJ`RwCw&QT(((I%d(5hJuo@U2T0TqsD2d zQCDQyzci|_lM~AgqiLfSO}j2=XVxQH5L-e88Xx?v%t;un58|McXegL@wN$^Q)VLgF z7Wkf3vGfz^o9#68_P-aGj#-m?wFMIf2B}zO+e;LP5(*~KO~{Mil>P#!f`5TxPfv}E z5!a(jJ&vj+o}4^=TZ0k%1B1koZ+Qb_2IKrLBtD1Fw}Vv=wxJu z-Ib;&Idw_-?E@$V$0aRn;>ZD9L>6WWL3f=$!ihHq9npTRa9DkU!7QcmQfWM-LH_cx z>4z_!gx#P6e)9K=jkCz7F69K1ZBBhDpV?xQBCa;Mx3ehSUp9ctHS-lhle~Zd3B4Eo z3=|$S1VC$O@2QJ4Vj1I(7XN<5N=a5tbE|k+wqS~AzyU*EX}y?8l{E+`Wr{=kOzX;^ zh!;w0YBRDebDj@(SGjs*>(rd`jjan|P$0PQe6oEC#9PsS3MZ9G{hw~4tlV=(!~r+m z5IBqiJbqGiwZ94G4|x12^+qSnwL#SfUk=h)Ei18qYMQRB?Pzp8zZYV0pr;LhhT7{t;~*v3 z9845FZ4L$wfAC-6==(Zd=!pBE?O(C^j`C8XP`L2t``hiB6-LO15`$@5er_>!12#f- z=Z#wSm~0nvWUQS(b;t@}4-8E(nRnOmpnd|xE@N^?=Gc=>({d7l{|*y3aU_7m7a?mt zO5ci)Z0Q5zutZe!3P>LSSLxzDJv3m)?=*Ig3MMWOBt-;PDq7;}h{rW(%a11f-9ayc zp04%yzec>KY#`Z+KH12AkLUo)3mMTBs0rsX@CMLvvtW^a@d@Mf#JaO zXA7QluBa(|G~{FQ8A+Sf?R{B@ZYuZ5{>6QyWcb+2k$S z#(lc9;M)26-%J{eV@KtMR3~ zxH~Y#@Vi&V3mNh>0L>DbpYj6dsQlt|=i(uVFs462^zXDkEvv*ez6#x`cgRWHx*|61 ziKkGKgajy|q|%fG6!+OtADZIk^O4JMxA< zOT|j)B}R^cOkPeOmU=sEL1HNhjPkDsSkIPA8qmda5Hm-RUd z#oQ!qDQ#QbFCl%C5v+kgC9gLHp2mJQzx2aX<}2htOOIzVig~Y+FNUiaZRvF3!1!RD z5RS_1DMzdy|E6AGUsM>WxsTJ3=E&3bMJrsdR^O4^?<}VP#}+`Z6}cKp@=}-E1yNVO zqV;Ck4L<$lX04BHJy#x-+k(83c5(U@rb=?|7RRKQ`XHdowHxNyK;gK@!7 zmTn?XQ6v2CZ@r`Wi)CXxjr1ryHJUU`5U+QjCf~R5EF!`Rw{`B;`4>@g%KSvge-xjPaP;l~x z^QEH?S6F>(#d=xi?TZ;=pz%=N39dwsnwX+4xae0kjqKo@SGg?q`398Pn}YU|1@!mi zE}u@=tcP8zQf8%iYf5}y@VZI$$>-SAA=GX4aMi_Rz$67R<$~?DUj>FIWTVq6rS?#{ zS^p#ZMZPh^^P%*BiQ%HIK>ldn$6!Y%A-k{!`B(X>Q6o|?+X&orkckn#%1qKFEve2h zrP*d>8va^DEfXny4_|s2@|mD+`$5}~!#Hc{@pWtV)|H?1*^=G7Iqyb&vu*w^Iy-mi z0b{@WHV^l5ZF3-cZJ_;RY%;{3^LbtAzE&twbw1zmKHX*f=YIMOR+_Z_-I`+)P#yv^ zlqPw`R+Vo|L;3&#I)&tw*6U|a8ssVx0EP*~JCYyw1Dm$zV(*F_Ow50&6S?zn(uvf? zw;?7ri<9B@pFw~q<;P+R-&sMd=Oz4}Ay@DP6t7Nase#=bSXS8D5z~?JP&pBY$n~3>KrBk_YvV$gn%%+XS9o_~^5!?C?wNe*XaD;1s za+enbNT7fbcr;O|f=tXZX-*>-c|@>BMs}$&LsNbhZ;|H5#$+67TnL}xmEruUW0m^_ zJ*Y9{u^rYzM@VG*y+?+LDCEBf1g}#CVG9dS!(3AS6?)|#7Z27faPA4AS4`?7mclQu(3c$OL21yke2W7&&L>9U>8siA3SD%ydbYu zCb6%V&F;$#X6Ym~8d#X?E&N&SmZWY+(C0BaHm4zd_0t1)Yo@NpHr5jMcF6Tzv#>I4 z#shc|4r1>e1Paj~p_!KF)|IYs;MM3aaj8G?xeIfDa1ez&t!-mjl5?xE^ijY#$YP!Q z2d)3wi|h5e{U@encg5)`cvBVk{$KHShJVHGy?LFO)0qIN8JUCN*}bwm_mp8?g+~+r zEoxsKD)9CmdqJc4m7I;lkZ@QG%l#?B{Hx`!m}GTq<5%Me)Ju8S>M|+lg0dD;i8whz z@Wn7_kP|Fkd{#eZm`dM&30)5YtR4gk;0>jEbly|Y3_0~he;Q8q)l%y~UVa&q4DIqi z)#2QAhc5~hr1I~^?Dc>|C#$HILhdW2T6RlR&3+XrL@DieRyhgRD4l$xeWw!#OW}D@ zOYhPx_TVHIIC{RkY%7xY2(MQ6E}K5KB=cj=p_jxnK&jw&ySwb_*m}@$n#}&U#NUVA z6O~f3`c~hOzPzUi-~3wId*Jo6FPwRQ1v0#)qDgpUDv`>lddtA6#yYAgdeh@HTfo?w zT|AKF*+u+kJL;{*mj=Gr`Gco;|7zleHcT2r&wK88y|NiDCBiQDj1+S2rp>SmjD4r< z(Cyz89xa90CB`z$jm;OONDG=S@Wftq|6^W6K;!WCRq<6!JPoiwdkRVdps{978ToTJ zy^WR#_CSO*T4#4Xtk$<6-9$yRBQfT7G0~lilB}?gxlYQ3+6twim#`qx{<)X%*_jzh z>4mAH?xmw$dt^Lpn&QCPEHD~G8&E)1_bA8MO^gOFFa;|0>Dfy8I&6=UzvVVjoUvE4 z`2_?hdF@AIj1ygDE2}JvwE@%X@AW=*#&AI*C6OM-P-)i->Uyb?Y2D6U@fcAJ1f1lx zixQNvq}B}ctxvt4;lSQ_*tE#yxUa3RYqGG6q0EpB*f?tLH$}Me8L2vv6@_4a9`pCz zdi&lLP;vEJ>gjj5>FOZw2dJNb1u0m4ae{$75KZ6=N8QzJakoC@vQedFcE8gB3o5Y> zm9$=5YyD0BeCKJphW#* zmF0b3qP6(PDK4cBn?$(w<0SVd@c%(zKzVmlp0E{gq`9r%mbe-}43j8BJ0c;)m9eGH z${~MpbeqK7UcU=eN#2TKSTScx9QvJOQD54i{#_@PqCGQvUycaNZ*A8k2a^DE3}&(~@;)3} zmo}s0agt%ko0PE3W+l9P3N8}tvs~OK_bq`?W`Jh!P&|^}k^Gh0Oj}W3^l7n_sb6I0 z;v3~t*jS!#`QxHxMVhmAzL}o;y$A|lj6wF@45-K->nFQ?`}St5*_Ze?a1>uzGP3-V zsq(yBLSD}r3!Fm)_G1u{48%JM_8-{)%OagJcOeueK7N7K9N_ znhjViNGOkY&keGm@<)2NP06bE2OHZ`x#Q*pvDC}xs!_3U-(h_!jYwB+k zsAJ-*_i2WJKmY(l7|P}iVcB~R(8KBO&CMO4>Y8zvN%WTRuDoh6EZ5x_|0w4+6ks)Y z@@oJ|T8lsCVY_0@zajoy>?k^s^ob5y`FHrN?_^9J9sxeodr{coA_+%ltLSm+6tr@D zS<-y4ExvC;a?&$@blicV5BJFy<|=H4r=)I^YkGSvS+){fT-amB#nA8wBh{8{bk4;Baw9WjmY~(UJs!1^yRKk1Tl8de1+3EYv7R9cnROVb;^6>S;7i z=0L^Nf?M>Fi2iS1f&lVRLfN!;4xi9PMT9Mtp6e$DHIUCqS$# z-t!+4`R8_rtKGt1YX;Z1K>)ZNPh#ZDQz<>Qq&qMm?%Q!N8=gj8H)#j72C_O&mrTxFp=ew`Cjj=o1tpReQV+?jn zQ$>H}smg+vY6BJjqwvkLb4Ypl%y(qSaV0oYRaF5325lU@^#B@(l(RY7k2aZrXHsz) z@DikV3N!)OHbhXzJ6h^4{7}4v($Y-+W=GHr)+qoDss$k=;pA}DIfg! z3??;7!OT^Q=ZX{BQJ`5&#PM~(XYilGGkhO(3ost+u4q0Sg z)t#TVJO}4>@34wtbVTAyi~4w%_lFynQ|J@InFwAA35<>L9`A|rJ+$uaHv2nesgo0| zix5|-{UG1j*OKS18P97lHmc<|SVOu6)&;X8X z9>AFIoybfb1cCry6txHIW&s6(MIRV^#htnn27^AkoSybxCTdNx5E)S!l(PgL1=3kB z%bu6;A@op~wKx7eutk*Qb4(5Uwdn8i=8=At;U?s@%RW{EDfiv7NBF$XT60&{G9EVHG@Tl{2pl3*9 zt<^1;yrj@9)g83k+OG@RB6&x_jlF|)VB3Xxug!-alroiUFbMsw8*!+x{Jgi@K$1Q-fR-GMWs_ZoDIeJ5 z#Y2+fO}_nxZ?)Nnkw@!R9#(}ut*e$=6Tai7IS8OJKmh?$EtE15fX^|2#Kpw%y{%x9 z&b+p%<9XqmVlK6``2oYQ-f26p$;?%zqN>U!bIG$^cIY)_iEKN4tzJ%sCX=fR6IjI% zS&Z6r3Y%H*X}8 z`$WS+pPYB7{;E8;0WhP`DbOJ(52}%scftS}Hed~tZI>nvB7sp^F<z;R|JogdHoT<=SRoUjNi;zjA zKV`{^0Do1jgyx$2I$3JA!l<-x#__#I)(#IBo)(`ef#a};jfpH{_$@YYqI^e|Z%YgFFIj2>hayv15(vo|{UX-{Vb zVdo{jve+J6g<(qcq^WIXmoAH5^QIrbVpv2V+9fO@0ZKV&5(i?vj_I3XrfVh-8n9d1 zzLSdnGv)^9o#(nTrkmV1hrDsRUdVTM*$dJDDn%eLR0IPoElK`+-=t-kXaEV|qSzS_ zJf~=oA>wG&H#_KF?4ujPOIw64?pTo)2ifc-rzUBE9&RbO*YuS{N7RZTxPEv{U+e!U z+OZ5aV)b4%XSG5Z)J(}4yiF{b&@zyXWMQ>j>HFiQma^o$U+3c(weS3N(QCB(N7(D{ z`59W?T1bolL^mUyAcBD~F=8S8H`5!la54p?GAo&l^MHJjs?uaZIS?>FiWtam3k{?3xPPjV5d`_Z_i309>2wC} zP9MzX*2bsTqIVX9-)>|Q7VlhVKrA5TVeIo;S1;vQ=+zc0D}dbSd0CwHrh(z3CYy8> zgi{LILwe-l^Yd2iUUSh592MciCF%(5z~3ADqkcbZj9Rkw-lNSY-vS(SZOOW@4LxfJ z%KRF^>t@0cy`a(zF%-!G!7ZF$#CsM2MagqUh|p`M+9Y`>!mcVf251dgP2Uw*I!!#K zMiC~HU~Jr5Dga!f31FfYG&?w?ETXG|i<0-hSt}uO0$mWiI51cw1sssMMsW-t1ER#t zFAP{VT(dcsh3GZ@1)`v@f6m+Umvm>(zj=0-l80WpBXg&M6h=j#t42CNWD7)Pss^#6 z&~dnF$h)7GZt~%WH>bBP1E88wnpITNqEym6ygQJqnC-5!$4@Z$bRy@Y>zoxcJA3}J z<3vHvCjKkn(s!)q2)(m06l%m^v3ugm1=58IjSSn@_LdrgC-G+JcJ@AY!Mk`>o19z% zB~f0xUbzEex+KA*i`ZL(ZAMHi4hgIi-D#0E+rxLA4{W}7swL~Xf^GC&nmea7EHk%u zTWBoJoKD0a-O2hMrZ3V*#@w9$_sFm^xYzR=$0@QPLZHUL;*4F0IlbAHA%+VB(>{a@ zd4wvcTk=5)Qz9YFqDK>r+_2@b(eBdH-COtfL5FJcT@A#>>eNk)m%%e@_O;R)s1!S$ zx>Uph;%-;o`7eDK4nY8~)`K;XdW(H2pW*#XU2P@noV;7bLILtA2e|d!+4Pjh2hxV_ z+N7Xczo@F$5v<>cm4hSpth7rE2B3=UTE|Fero8$H5&llvLbSibu|7{McDLtX-QrrI z=31GO4;?$yfAL;g0tjFj1p61nH45Uk0=Rmg%oAifM-|^hZs*r)G)SlVyh+rGAly7b zC1bL$;d`(H%luKeri#M6=BS=nvt9E^9hAjTs`@o8bgt&=fxk)) zf+n0tO=J~WO}H-6N^9l`D7lzyAoH~nm?}KNe>)GK`kQ>EY(ah#c##^2_PIe{T(0IT z=Hy^7AC3sB2p*Xan-wFhvE=32`w9c6l~f!_z5!ehjjf@yLJTVanKwf+^J)k6)8)#z zJyCpxJY@p2ENec@1(q_Z8)%-7HjdL_TT`3T`#)@#a^seY))?Fv_n9EesAL5hjUD;v zATTi?WL5cgpJwZZe;f1G%5pC6v$MkRqo`YBJhWPPI(Z`L)mQOV|m+)6LHtw76hjzx1edwruq611Z1_9 zokolDJh%x#Tq|{Z_D|WgTX~)2!+YTA3-A=#p}C#ia28@S>d;QL{)!mpmTjdNt&dnL zzDsCT$EIRIR-4iEY80~*@cvPQV(8YChkBI(>#MU)z}3etOs&~^rnqB9l z86doDIjvDGJ)-)Nd3kDN3e%aW5B8Q#e$M!?&NT+VMr!3^#N0QvwU+}u(tf^i7USpKrn0CZm@W0AjDQh1^_mMBK3{P_{0LhOHY$M-rx9i6z|LvPm?5+ z0EH-E$0^?My0aEkSVmJ(-UR^rP$#Ak0cgA=h@jd-htzdF^MU&ezaeI1<*`~CKVI>N zjY-Rn|y-1ab8m zrccPki08sP_$)94Pue^EG-c_0yCYK>2`+QiR0&RJnK~1hq`h6a~53=G8VYmkU7iMb8wcI{aJvnGM`Qe>6q;lA!Hb*G832bHg=go z+3VV%d6MR=?5i~}08*Asm^7Ivw&=51%V&rlFc{cDjyZwCpX9NAPh^AMf8J;$CkHr=U5GPkqaH91l6RfnbF=<@?Y{X?s;q{0_S zH1ZA{)(M%Ltk0**702&U#ZiVLRFeiub$ypCx_{4Zk#1#_0FA~)%>CN))I-Fu7?0mJ`=n8Y;Ov}{pLDu>% zMOmaju?l>k4jTH!Qru9ZUntQ4sGXp!ClwfLX$x^)9jA`;;VHBF*!E4x;IqcqdXSzO zmC}tlC2vrwW}tTvQ1Cs5@Vye-G+1Ljy7XV-j<*)3p}akp8lPborU+b8FZKodwVb!g z{Jbq1>}qp{WmaWHeJVFi{du902NY0#EU(EGDZ*~YV}FLP?nCPT1SgAn6#D7|3(>D) zV4tql?sEnQ`2TAIWQ#`odSN`}l{rsoje;%`A1;USApU^RrUe06rwf2KSn&yo3!t4H zI_^{@XN%J=bJuLeAkqJ3+D{kj2ie_}Fi#C|7jG$-jh&R6+d>nxTFFrWDOY;fMzr?W z=|)cAG?7?Sl$ze^uO!Bj15pm^CHSHzT5ssK)y-q__Mor3@{|p@?M4io)iL=(@pQ$% z)W{FvLO4kjAJB^0^yBomCY@TkQqDBwWy*Nxdlqmu`%iLG9B?ZBNxMYuiB7jRU(c^L`;Aw+~bcW!u@an_c?Rqh#-Gu z?IV0d;p|U|Fn1loHoz|po;8MmKx}_bDZr42TZA$|&y1w{iafY2y`6)_N^`Udhr>7$ zhV*#8sX(oOci`^Pq3TTmg9ek_2RU&NAMPevPjVU?_F`$5E9+r=e~LR-CX*xy%C57f zT;)6esopZ+U`?FO>jCwel}0&+65@enI}w5x^C4%uP0;go8i^|fCIKt}YoiH)y@KX0 zH4B_rXodRU*+?1(H;6e)@+<@K*{Db^sn@o(R1uhceXY%3R?KqJoSkk-1iX>niHO zX-QXFqehA!j>93z_D>j;7nr~bw@;p7{_Kk{11pkT$b%S%aZWs@XSl6yH2v~ zeW>8NL!+=m1UZGGh7U&pS^&j5B^b`3z*aCP5&%&4iwOkPcw(ppSxbqvo>W{l zC}?2Hy}qwLWokTyJ<7l5NOi%Z$eR4l_>uUJt9m&{Q-2n3YPzyXUks05>z*jt5Aj2! z=7qLku7i+HHZ}xBJQjovqr-uZ`YRV}Px<6+Z>enhyb9F%hf~DC-r`@?v)*G{7M>*C=7n0~fSSv7*F5nZ{6t%X?Aexc9^rhrF2nrbHLb@eF zF!Wv{3O>;Rf^$$l%Xk{Zg>;<)Ea7+aIAp7$^h(ADTopUVnU;=Sf$K9>NX8xxv3{xf z7kBRhttvMQx^X%dcJV3078m$XO~S|d7G49Pq?>1JD>Vm_Z^LV4WI|x?C@%_GH$B$NosA`2 z`<*aFc)y3S%*E$_t9v8g41xVnPcKXfBleNRitm^(?296@$9UjT^g|v z=A6y8>j&ZKfkjX%sql(i__pw%TRO*U3*XMV%<`^r?JQYF6V_m4PK{NtT>k z>&6?Oo39kmPyl8_BAym=(40)hgUcnus5z*?JKH1uWXoM?d8>zL1lQHSUrccIxpaWa zg5djAhx>f8|G*$XFfo#Lqds2#EMZ`(QuSuqtW=v5onU66r;f)GJX*y!LJhpA@ZHD^c&7@=P91sN4n<0 z@5si-y}ZYQEuy>pH)h=o#yUEYo8CX8?=qur*L8p-DfLJ#v~_Yo(f}br#q>xk24b*S z3yVAshQP5}ieOfP5@vP~>rLZX7W z@xJ@Gmicxh;!MLpVZ=8H2B#Mat$8sB5D5-LmwUA2l zaVF=SG`QyO424E3ot5HfBaEsQ}xbj}8gX$`k7T>4&q zf_gH1tI(jd*{{-Aia~pMOy`{*{yGS~gWnIzmUQS68N)!v#s>ZW}4!caCSu#8#>S0k7(Bf;C`>02Ikr1LVL=X*7Kmcm^m03ds z01u}W`h{b2cc_+TW@cu8nh=9QnVFfHnVFfHnVFfHnVGtw24-;RL7ADEnVFfHnh=BO znlva!;)Hq-jB*iJgliCkT!m7F$U%cu2sk9Ok}AeH6L=$RCN43!OWZ+`S=vWf=OMF|Qi6UlYgzgm8^BsK zUa?5+NUeWZcJ(Y2WA$Pu-c+PPM{%?K%r>)Sr?1yiguuJlC77J=_IQQCD)kIY{BX6N z$#^I)$Z#1@AQBuHU=RQR0hxlMhNCv1AMKvq&rw{$L;?U0wWnY9XPrSu9o&hVVSmI@ zF>03#)*D0eLcF zY7$7y%q4JHJcUUMq?ayLPzV61AOK#VxLN6(bId>;#y}{9#TBF9r-6QnwU2p^YDqM@ z0CrE0fl0ij8#b6FSi9OX%8Utze}nYFy0oM4D9`2K70BLs3uLQ8ep^Ul?~F*<=J>cQ zuf=QjUgsfAtQQ%i&{L6uvBShSF6kof2Nav|oCs&i&335)PKc&a+SG2~Gy3{#xfsZ! zOhFaXs6_0xw=1x8Z)-_J03XgilvUxo>#@xtp`PL{F*Eaydv|=k3;pHgt(B?Yd`wZl zn29nlW(@{N(X*{EQBX!?W&xV$p@<141{FZVB$AW^G(DOK%)zV$5SXEWIda7SVS$2_ z#R~yZ2@n35ri%H&yeaAGje>p}CyeD9whX`utKdpzl`+rv;KDkS$ z?ViW`=p~JS2jfIaBGH)4Cc{9oql+K%ziI3s4f7c3krm-JC_E@gqy*L?0JyYVx0XEP zS#D-0Q^90ViiM9z_*!92&O0`GK3nPSCQns59y%FL012IkZ{P_$h7Vj()9)-GYZeq1 z&}c$N@CH!@8Rq>R!RoU*rKA8CQeCddyw$e0+uidYSQR!lt@t&?Af`uWD_(}rhfr|w z(7+G`0001BKpxoic*9X-s}~lzMN)h`H%9&d$xZugUUpbE!Xd zCF1Fg_ty|W5H=9DqCmL2aB}ck=`GMyC_@Y+HvBQ#3QA5W>*>^By_z+rm^F<&yGhRe z$l9fc)~(CG?9|fpq^lME^hoes+Y7jhJ}!OVP5M!|^1(^xX+!PBCt|~h zU5T<@D4IHwcQ`sUcpPHm z`!cR+_~JW9jKls~SZ+kF^*(D!{f~5sQedA+=oTIzQA9N)1HwfgDUOdp003Ad`yo(3 z0Ld(tSx}+AQiL)my1Q5HY;zA+ezh+223>gUMSJP8qJ?Hi8)^wzQ8f4Kw^)s(8o>il zBMeK3uH_u(*J6?OcnMlKi9{DBM)2eBa`FL;K_Pl9t4Lu2n3{;kL{4o4IQv zQ;rSmP>ZDQ6Ezs{^Y_l!Ps?^isHo1BaU;o6*o!V9`1zNd^hQcxYUvLpqA=-2yesls zU#xPfEMJ8D2kYnVu%RtgN^qv4s!##|1&1qd2{xHV8Ydsu8L(}(!P#?bLOnfqqOO0v z#+OGeS^eZ=_hZu=-XGI~6_w~}=4)o*ij-;S z`jrVVf9)QPI)MPB_pt~hksV)LHUSZGQXotNvuL3SOk6TVueL}&U$z1sBJ@to#*&pZ zQIhe|ZXPk%=zeLvy~pqBWhvB@Szn{#-uktZEfhl|Izw@Q6;_X+ zz~5jUA;DS`)o3u500JPE&ku7gn*zdfH^=4vc}U#+s(SPlOEMxIyMrKBm8u@7HJ->(7@IU~E z{I)Gv6%c=#$zHv(z<>hVm|b2~PzV7`vgsAWC>Aqvv44~PNGr$DVC-t9CbmDU#0zio_ zCtHC4iB|I;Y2cq0Bi6C*6EIjZE8{mJi~G_#XmmLE)`|9f=T}DyCIx%zjTLs%e~scN zlv7R7N_=T%KmsW7-R-N|#Y0e$sit@AyYMd7DST(Xaf58m4yz&LpzvPM^V|D(!Jsk+ zp(`~8P9rS3=i9$p^W>trK>wUg=Sfqh2CX6gL?n;0Ey8Y2g~n+gmxn~a6$UWEopm7q zn)F@R@~I0-xx6lQ#Oth^#J-s+A>g5%dwO|U&ZkK?#^_509WjWXyy0(p8&7wx4{yE; zh#9zyKfA$kE)ZAkmRK|Y8hZks57Rx3V(H}RlWDo_@3j;NF}3!%2)-=(v~qrzy{u2g z^LAEzhd6&uC%kr?qL}pjI-4+rNQuZ9f^5pJv_8CF@1L?Du-m;Ow?qJc9M+gK-Fq9C zHZJY($$)~2vMGU|3<1%X;0gh97)^&edzRO1eR}dadXg-seWD%UDz#+mSs^37_pIA$ zrbSWrolebKi&;c$Bl zcU$fMA}t3DXO(vv-SCjw@#mHPY0l={$LDMUpG;;Dp>hN02!sdvoIpI13G98rSQ=lT zP==MvFb#0Zz27C_s5%S~BnuRx&o-Tk*RdV5_Ea2I^^JH7I3Lit)O$#_p0Q*hb{y`! z>80hkBQQOb#!m70<__v8x0Xaq%z7qUg`S0lP*5jgE5JS~&8}V~^p&9)xoIG>q)-eP z&jB$6?2|w<#fY%Ca?8LK-a{qj1Ayj@!=|~Hi0O`KcN0x<#hkH z3Q)4@{{ifIAE3x``mN7Ncu`xG<)uo0(skhqv;W$djxxL8^ToV9Eh%!4HfkkmvK~ly zm}D-LWnAy-FI?%o$GkBrSai@_{#x_)6ak6E0M-FWy*{hzSQpZg1EP!@Ws6kl@E+(L z*VM4gCxec(iwXG;1oxk3WBo6CvVs%cpU7Z>s(`617bMf(2};Y7S3wHFa{$GPSSrPF zFjUoE5Nj`77G9L07hBDer*-MAvEV;l1w^;sZc_T=WTvRZTB51%aSzuv$QGz_H1}i2 zAVyu;+;a~-&PfHKahO(NIa$KfssYd-*HY$UD~Mjb=Ju==p1af!$DVo)2&m|@Q=c| z&u=Y({sU$y@VITQQ&^XDXwTFV(d}=@qrVH$U zRVhc$L4LKvvW@|5DGPLLuYAz}KubC9e)E+c`#3o-kNtRSd6pyz5aiPF#sC#&-1IV2G> zmS-Syr1V}2GG*$-TPbOhjDjDw@?ntz#3nD(iJr>-^5DADvbz%>fLFZzHBEg)B&%XJ zv(xW6J?%Om19{;NTp%0&B}wUK{1U=;lHf_}o3S!<Z98)yjvO zZ5q3*f3zt~E=w^@wDtJPu+&4toS3Dw^F(au?Bte6Bo33wnvf6k8aC8$KfE&m<2@8H5#7itn zy}v~*u-2?zrhL_To1Sc2DB(y({H+p^?8%XX0Re#&aEK342ln{Rdp7RY0;GeYKbOBJj%?4U(94aKc|tgQdn?xMs7Z485M0tfW0dH zM%*gL2?Dhyp}=;*>g*O>3wBzJE5TLhIh=0{WCZ%?f~Ly>dj|QpDZR{{(r@$Ufgfl1 z(R`wC6fntH^-xmL)R+h%3nCTt*XPgR>o$>ERL<59K+{f_KnFnn+>)0fCqdOC$vJ^& zbS0#jt#wnv2OE3(SCxC$AP*N_k?gL_?dfNQui_b5Z5dz{nPv3 ztI~<9F^9CsAGZCJN}ek>hC`-5cr@3>zLUzn#B2lLJ3NT;J0hFLFy&msqpP=&;ItU7 zwxROLvVcgP76n|7lqYdTEO;`M12P^SL=HPDRj;UkA0q+G&eNlway%TA(i(-Jz7$?$ zH3>(dGedIGAe&JcQGGg=pmvN5MW;D+bs!Yj#%sj&vMJiuUFlRfim_(700imqj}JP4 zT2lg0$N>j$4osZtyisi8Vq)vubkMH)acVdY!4Vbkz#tnKC5(WJG8t9d%0<~XL=&j= zXLEO+8wJ{!4@c{L8=8MY@#v?ljJh~D4UFsC$fv)1&6Oky0q!>$)U>T@1RAEwCr2} zS|ayG61d|gW2m9CL8UXh|+Q4tK+{xkL znA$0}a8_NJGC}|?LI6F7BeiZc#D3lD14fZR?mmcSQ*`<)TLI;oub)GFw*#8PdN>K;lvFYMMqNj_GC8(i3I`Ol z!p))61|`zksr8B-G@D%FE3d^^H8fm*22b-&uVL-eVo4+E=nuyBPNS}q2jY{+v$v`<6p3$Kv34|M9S)xWly5}+aaa{nWW z4!Y|N{|eoCit9%7u5fw(VlDK7Al$EtBBIij|F-YCq2BTNP{~73MwJ5AX{{B#*~--_ zQ-H&H*vqZ_g|fq4yd%>dtbdP6?!l6(w~--}u&vb_lRJ@Zz|&C%6k5?JnD~1Q0au@I z?>~CQc_mM0oZFS7(^{?;eyWIZbu&rvX#(IkIVm;gvUzU&Xqwf&uHaGkd}da?-tyQk zuqJJZ>|vUFy~YddM-?<+z+JuHUL5XJe4T3Y^PFAMPRk@`E?o(`_@?qDboB9eX!AEA zdOw&FVy2x_&9jd6{kK+<;w}Xa4Oe-I0>_=cV`@Mc1&xP4svEN!dopSAahoG}M^&UUl z4M#1WcK{nx>QVsR-@6U%`AYzh+gqzbE{Gt&1Cl!3FVaV(=xdzDk|i7qo;|Bj4>k)+ z>>({^LsuwnBy&pH|N`{t<+lRqiqZ*}UuTlZ}gKf-K2Ar;$KmzA+ieftv1 zXV;fpw}}x7iJbRtrHWp=Og+KpTfJWa9ziK#l-y1sD|1@uU^9aMRg1qqMX4sB+9MwFY!Z1QV9! zr8vcd$jE*GBZ`GVrrLM2yXXJ|>=XLLH)#+iR`whP+`dmX8Ln%4bI*05@9krW0ZOkIpQ z7z4;)dJGLTmoIID@SR4By*mtis=O%r(Ro;>D(N!2l9`k)K?!Rg;k^mFssbN<&(OYKa$M0_M6sKHd8*K7cV$CUf zOA32*PD6s=7&ZksH48)lT@zz&*X-Z$P|fkrGGLY?322%uPEta8U+qW-QPSY^{-L%z z`BBCrFz0lXh@GEM3f@2rJl*>D|y# zs}KW72@QJIqpr3vdtR3+vQC57yp<1u%`3j> zu}9by{irM5l$%TwxxUP4V|~<{5h1(rz2-4mh;OVW^5~8$Gu#8bkbAt6}HnZ)ms0 zKsD+JyXTLLjId|3&g9|twimo`V7+8xYMyeM%2%Z;_1syLsne{84GIhCGJY^$ao#W1)YpErT3s(W>3%2m zp8vKMNoMtx=D~F=3ufO#2PcB3VxJk@{gu={A(Pf$Ec~8}6mUJkS4(}EWTL@b+l%bV zfAPbBt^7oG(`nKqr2nf4u)jYFGVy~np>4DGMQr_`PASfo!?$iIRte zb-@;wgpm&0zEPZ+Sllls7l^Ub{8%r~>9<}l$-79uPfj{glk7dRGs+SRzp65`AML=rJAQ z+#}hwTy(P(DRP+Mcx@v%Pxdvd_UMytiXkHlO#TZ2m^jI=QtDayTK!McK2tHy)LAkU$0Y!$@{8Mrl7VtN#N1&4umD^`*u+3^1&iRj( z6HO=&Vt|`^pHOz_Wg-3OGRA5Sm+WTiH6oSHZW&(Y->N0j^YbH#go7AmO)gzlIF(lw zA4>MN&ztr6L+ryh`WrGIt*LS_e7+|hWEJr!K?B0;!^3}=Yyl2L-dW{1u5B$|5I7k9*20^#Me%2!d<;I++t+`YiH(wFs8eU$(bqx8~E0uz5iyPy5Ph67F#nNxv5i_WeTy0sS)29K*2A=6Ln(* zyu^W}t~qXU8jQl=Is0}&J4Zucke~_9Z&0k)zg>)?K5P50-bS1NS!tU8!ttW~HDb3- zH9`sCruq4eg(sR~?P+nDXIyX!2H(p!)%6t|#|Z|5zPxWt6qWHXbQ_(}dV~Sd@(OxE zhrNq{Vt;2{<2M4UkEG-YUsg)| zsm*!Bifz%)FZ@UdOzcbiBf!r_6Li|@XixT}4Tl4^{XC1!c^78O_m1jCI+U%?uo=2> z{00lT{!m9w({q~+(%!wT<#P-nDIn8bR6V=7b?Nar^cmtG^*4Cu(c3uw$5jq0Y(r>x z{-^9H01Oud#ro5@*9&n(jf> z^NWt3Wv(nXQ>*W*4}{*6=DC%Goj1sJM>!br*!p2Ey(j(&hP>sZxN>eiC zDO*;NwR^8lh6MqNJ3#^}h)k8(eleZ0ESZLI#!b46{nq2;1Ku%8oGoW_6n4yAJ$i3X z9F@96nq4fZqB++t<0|@qm;ltyDDg0y=KmnoGs4*Hs81CCrBcB z_A2uu#R6%ZmLoGFn-pg9RA%)jcZQdu{*R7<--o}iAh*AUzH!XCiZ_D*jHRUUOy%kf z)%hjHjrs_oeVz7g^woMU|5QoIYvdo-m}U3t=ks=rcj7~+kOCSS0oCsik_KSRkZcj30p338 z%~XIr>Uzq2G-MJ5Mhw!wI17kjFUZX4pIm&9eSw@m{ z(20RT3q`2lFSCTSl*ltt7pwV_^UDxUImvfK8h1J_>hXEXe7Zi6ekkp?Q-aCh%t?hh zr?ok)>Dp`-&IAH;wdArr-aV$&a5cqqgAyX=#rSfiEqQMkcK7!Er*_a+1nlLt{4U_u z+kDq%Z*&<2&+S@aYo=)5zAOrHuorpKW6?RQ*xRgcd^7BRZ-fp_%5~`u=ZgJIAL{r4 zpp)rA6{KB9W#56-_7>6ur`mZkhDX@r>WjJE3gUT9+f)G7s4^_elPAp(lZ0SBLD{G{VH zfcQ_S!vH?4daA1*YV$pbH@gSv%8eHTGwYA21dLbOF)?Y3hBtfoH=+$gZ$)Fa%h5AR z${wovY=N4?X>llEt4Z1U#`@9DGQfl3zOL$WlOBT8%|T91cIh?Hy=_O-u$>=q(?U@t zaRb|5pNXj$?E=@EY+L{$3W1@fIjK?F1;M&F5_GXQrms>LrDbf5*1~AbamtujzEVlL zozSzb*>j3=)C-@*bi|~$hXMz;95_V-K}ZzcW~ZW2UyV7WOtNNPvB>J^wi+JZv2^%A z@7S9-zF*-jHSW)%va*VOelkv5v+Qy*B<(xw^idO8e}2!F?6c7)7lJL`jJqJapn=E` zvBoPZKpH~m98L}Vz26A4eDDI87PNV_7_{5h7F@iOG$+V7m$3d@304cuVf&|g_anrt zEdwR)A{q2b9LO;vK}wz+O@>1xPDk5{Q#p#%@hF(cc%{vqCurAI zfiI6|=0G&#;sD$lc${Be6NINAuZRCOt=~}(pSXP+?n*EgOCrG1hbw3(fp&{TGmwTpuy4t|#6HvJC(F0U5Yt1ew{3@q;0>{fiF#Pii79y7SvpLu>! zCK|gp^1aiOK9f`mRiCUIho?a0jo6$)N2I*Iz!eHf)t#_;YiJM*k_bbvSFd#R-%(z- zqNDF4_`YAwdU%j-wVm8gO(04Svqj3LtL*d}T?-abo_-=mVXr1w#GaHzlsbJ&64ZIy z8hPo>m-4for+K{yr=ybS%R1-lT@);p3qA3gbvmKN@p*yu7E=j77N+_U1EP`5%1{CW z4Zr>+F@dXEgOC?m7XBONzw)tN-6-863t%G}*UhEMf0B`Ox9w+sANRk7aE%7%G22Sc z#Zxyx{HbiklpKM{RSocX59Z~J;l&t$AY&C=%wZI%ZW|Z&su{2^-`};i>{yCnoKAi< z=&e|$_%8d$`rle!9sVGjhr7V!yhq_0w{6+68R2;F=bGiIBo$^%oGE4L!e1dmX4&j` zs}+lFdi11uu%dE`Z8Z>kFr~j-q3;Bvw!M?G`v-@CMM{ zcfzP}rk~9sF`mG~>m5-%GRAStli{i^{U8vQr*;G-v0PAN#K8(&fTryTH+#D zkJ58(ReHuE3;g%2Vg8BZ>HpX=5-UR9X}kfwp$)^`_iymFYP}R@nkL;2xx^Dp4?@l z-orkNMSs_Ey<8rQqy&`^LIIq^8d@_>GQOYpXO~6hlqdOeR^sRn`WF4$m-f^j#@-&Ndza2`S*0v1K(^$vtJhD^lF*#T;U=fZHWbuEVY(Cv7zZd|A`JR7q< z^TE&&ZBOzG>)Ck=qhj5u#P&W1<8uemhez~{Ta_4*!8Os=uO|@q-#f>5{~Y$AywGwu z;>)>=)(a7`h_FN|`AX%tTWitt0RaW9wHnR(^yB_KYIp&QS|!r;xM1T%G%;|fwlEXp z*?&!S8STZWd{_|Ngko6mm3gudBA8hfm(tUvW_8&i^u0+PxoM(~C}Xg3AIQt6^Bj8oRND{%Qz_ZV~;c zp(hJRnsk<+e9|8c@Oc8u1%(~tEC@QDw1B^$8gqqdfG~g{fDT;PD6AFu@nDaSx~h2e z*NN=4vr>4pAI$B8Cen)F{W~;(q1s~|`lPRhqqc(BiSc-P4lI9Rbe(5&SL3O;#zX=N z?W3hWfauYHy9@{a4R%tLc+MAU^P1(=vm0+a?(!wkb`aMl`n-Yhun!mzB{`miRghK0PjDmM+3q_17F4;bg)+?qHI3kX4=b)IV zKF6^NlwB>S{j-f;*6ZA_8v0{iB;9Lt1frQBRrFs%(n!`i_}&udX7*O9x2Gz7YYO~g zAPghL1Q6n}K!kA&Cg5a&X78;dT1j`#&oRInNp~Y{DYN{win)PTqmz^M;$F=f?X`|4 zU3ekT+_b|$k!h39KcsF>fRc1b1z1b;7cx1#lS2*{sA;3)wyA}J z7$q%2giT&pPd|?^j&+c+Iy{guTBd1cVwdk5-9QqcU<~;}9E)zJm0(}=6W2I(n4$)y zlHUu@3FF8-5#oVI=$G=*&OY2K4nAPoKP#rQT4WoEtG6dX$&52^TeS{2`0mvs15K9v997($+i#@xSM6~c2AaeO_s7WMHS{Z+r%a4gI^SjHKiHWeN(GymkC|J1VKcD&pAyH@x8;MK(*|U(i!^&>6)ixKT^c{q_Xk2d7sIy)0q+D{{yzAA+(J0p|&3PR1mfVMvYC(Ax+V8$R7bf(l2#U40F2D@{F%f>_N0VbP zgdos@`@mch9LUHK06>8e5diSyKX42fNFb{I&ah>1_l63hdnhc^ZpZ zs@M>217w2%-P9OlgeYE{-e(cryna*?#c|d0-L^M4QFV7m zv9K6(-i-M*H$9cEW}UegFL>RZX_bK*g&zU=XF1qDBT~3v{fC^EWhm$BpQ~;Xn5;5I zdYgkP{_2`HM9hYHJ-v4uv-WUE-8sCwYq^zo2BD_YiY9SIrFTDq#Ts>1zI&`*fufwz zCG&>iFY-7PXvZ4ImpVsRh=TV`% z7V;MXnto^l=mG;YzfLR*c8go5{l0ofs2wU>b{ErA=$G!cxh#}dO7)8RKgcwPu6OIb z>v&xP?t6w#Jj{&D^*g;KPr_=r(^I8|8}1E0UCc=I(Xa2;zf9W-{&-7d3C-+40MW$u z%FyeAz<>d953?>x4^tpZ)Gjz6KyyD@LLp30e|vqlV}PC(vP;moDzMyd)gM3cEf zmKz1#2|hOSlOU(1!sKD6HwDI*mE|KdZ)v|l^eA=h=4zE@oDA&ZKj$b8fk0~q>W_A7 zyTG^@12MU8(2!xu%&~TI-p(4UiJ1jZGX1F|E_0rvn*IJMRFaQhhE-`Eth%3mz3)eE zWV1w1^8qe@@yWJ_ZahR{W@=v~X*zuG+a`ODRzbE6gfMbMv77o2uzZ}*hB<}+K<$@3 zBe3uou!xl!AOj&+CyV;5q3X$hBhmC3ncCt6P$nbON&v@$A|RQJ`alMk7i6{s02E|G zBoS*@G||H4y;E@^WAC<33I@&G?>Wo}5YH=DZMcq4h7eIi`87)@CEx`A0O4+36;YFd z+1zbZb*C-+{YvUlp&5shG)?_{Ikxt>*Spb@ zl`nvNz?W?COTz2kC*%D(3OR3wPY%-?axI4k18#KIyRCQYaX3&IXy+P8-lK9R=0gAt z7%k#dM|~Zol?F;;Fw2Q!3L2pcz14W_lEIOg8psBOAkc@@fP*#}* zdiXdVLkMGhW$m8hTXh^-PHbbTfYOTT-MICj8~1h3Wyl2xP^lwaP6SRirOJn&YV@eM zqDa92fMARm02g{h1?~beRK9WV8rKhbvv4vY6pKLJ0|pgA3mb`bWnBn>1B?g&7zN}W zK~oSnS2PwOXOdKmfdFKxNQi+xHz=@52Ovb#yksGa6VstOmyQ+8cTBFA$`6I^((}k?Qx5GvcFH%t~9Uio^DdCoJVhekPM1u z$&b^juYMyrk(HB-!vZqM?}4Cp1b+WluvBc_zBb}e2WA7q7VWF!PYUd9=kgomZu3u+ z2A^te5PC@*9>LxlG!d_G*~I{Fka+T}^yKEBA$&&0hOs!PWu~grbn~~SjJcuv0dw;S z*L=tp0hQ(*nSkJ131{g5;U+1XKsXz_3sS;re>+rSMwh`(E^{cPWL=w&%>$;$ilJ=o z1&i5>G%^6$PE(~{$2HEM;IqOf-dk`qo=9z7om%Pj(nZ=mr(S^vi#1T=>e&p zgy}<&h%i8afWMsfiX(61uPs?8aH!N{Hr38H23O&uZ)NpWSzQ2l1Y`^fei0MRg4Mbu zK0v!S>P~3^(bf#CtWYHoC`Sa)1Z8ntPVbNb%~yu=NLS4y2-NDb{c&RugaF21RZ(s5 zyXuO_Uj$a&zN{x3A_9+X#b8$VB9!xSsiqZF(O{`+*ik0$q4AZ6dg|*GV+=`0vK-sI z=81@Yl045rzXUPnD4K@C`0vLonti@tEcoOsKb4$s&2W24@_OGd zTv%Y!F=zu^9Y`@1O`w&Do#qb6IxB7CVKmgGo4!JuD zu(~*cK>`8P5&-4ge4*F+W`|(B7)im_*&2m20uUM#T9W&PfXeBRf*cr01P4pO(GrQn zs?oSrJHgdBG4dPR&gOOYE~+87GJ2T25}WCHL!%(?9DN7!taT46z4#<@7DTI*x3{}y!XKdFcmo3LbttirF~QyN}j z++9^KKg5D#D#{}*ToR25VEEOx;UZdJXIw+4kcI@#PfYG`%@wz}APzpIdRg2zVY^D7mrSb;fuI+_(z@htDoa z*>1v59fdb_%=IYBb|kO1#}{JvZ4r*>W|)4lkERxb3a<}5JWXn**`h-I+mvfpi-EA4 z>}~to&_Drl$AG?o*(n1?(G;DYgZWH5Z_7Ri@q-ybMCYGQRb%BjNZmuV=LIIKiYQ-DjYHC zzr3oM%x-CuL>aZ{fIO23sO|Ey3OfO4K>FM(!$LQbA|!Ju?+euLx7qN%$Tm#M`b;JH zXEZ8R17*(nxJ$NiwRw8pA~VP zkY+%ty_oDGUPqRrE7KbD-*Fhhj-d$K84PJ{nrW*#xGm)tEs55?J=zWVcPs=#?nXYI zlX%Pw!B@m*eISHgiGz0{4g?Ck0KpOfBKrEQts~)apc|E_Px~eX+z}6=Hb&k~##{o4 zuHY3mhd$5J`vF;MANL5I`^t&s2ups4OwO zeC1Q>P|VBoa!?-`_zZ|aIJrYK6WXT6*e%ib=~KaYg@pizWdLRX5_b{R1(c$|S|6AI zx-DbaM<6wk1;nIY*-vDd$c@J5e=U+>}GMBGmw0E3W97kAqnM@vJL zf*ss;4u$XRMzNMGfk+^L4%*hNat^Y@^yQyB;({#!wj8`c$V#5JU?3%(L!>AjRMN@& z2H7|v&i<-8v!F|WXr5)5D4cr?MP*c1z~w35r2fn8(khkFsDbR+DKuQ{P6=JJ4@ABL z!^@{4Cm>`1GcyKeWDLm6h=-}XrTg%qhH}2!;c>riiV`TBhUlM}8v7-B(Aj;4M##}Z z5w(<`MDmEx(f9QG4ubStEcM#J_j@*0HV<42(Q7(V8mc!O?I&t!8qLG;0zm<=;bqIR zB}f1WfdV2T0MY^g0Mc0vz#sts(gYK};oAapOb7xY@UY0X!M(xDah`}k{x}laf}G^VB195v={KSrZX*#{qNR*qsrjE`ReA-&~TWWi8k_KJnu~l-$*V+o-OQQf?X+WilCBPNyvan8F@RA7{dObv2 zYK3!4@~MF0xBnH}>X+5`X! z5Fk5~7G2~>h`4SFd>61_nSoYdjQ;>jLqt2O2(!Q_U?`54Fip?6C_g98(&wh?*rBl@WT4CYn-dfs_oXHB2jV+< z9UGEP-s8xm0S1IV6DT*LnnDFP*Dy|WTG5CQtvPM6`wPF;^+cEnM@Dc4+h-eQsny^A zU**@e9ti>Sx39wd+uu6X7Toc7q4R0Yfk_i0ogp52is$tsfZ$J-yE2df5x&IvaBx>O z&YoIJq)1&%xjg_^b5Q!o`lD!|LQ>dpM!J2MQZkL$?c_}u6>fTeqPXqc)pKw{@8zG& z7D5z#ia4MPI52%vC3tDDa3B>YWw4Cb3iNC@+D|-x92Hf<&;8z%>4UR;V&SdBR>)0xWD$d^;UxCO?0@q{xmArbl;cn(?{}#ahok z34FD*5&(z?)=(%->bMeY?oz{g{^ErpNwuf|w_k?m`!L^`XF(AQMekg^OAG!T%lqlJ zEPQ@{>WC}Y*Q2iMK1`We>lf(l>oC2NOAj~zOkjJrWyIx+Ph|<})|RnJb@X8D-Nvgl z72aAt7YC7DT8P@t%D5B3KO+EevKK1@oTPjz3XI_yjsE&=Qn(z-Kfcd1=1=M2b>=_> z003#j4)QF;?L*%|*uR0By^;_>00p1`a2jzed6|`1*YPpVhZy(BEv#vx&Ro+nXE(N9 zDPWv}kXqZ6^V7!Cd*Qn9#6rIipe{(|5s`wf*Z^EZ_@Z7!lX2vMOP;7pX@P(800nn4k}~o%UIyq$A@cyza}!YEKNtV z+4bKk2u^`gQ28JQL7Iz%!l6Kg7FZ~w(+Yft>7if<5DJ4JKztb_GebhqP#;TYtjJ5W zUe^&<-*+4D^}*@$<68cB{0w$;x5sh>_zCg`;VD5UT!aJw34(_Nl87M0^JoZcL_`S# z8lWu+HUt5a$uJ871OoniSuZ6GaT5?6gD?~#+$t~H1riBylBnbmAPj=yA%0^T)U{24 z65vpFuDiGcA_`8OttF`7Zg3ACabj8aZ{XUTygv+Vf`)>+F zMg>y3?ZK*0F;LR06?f*X<>f|oGO1?0#gjBD-Bghl(b$LqMtIUjh!RHq6Z>4{tD{<` zi^Rf6;{PxEJ5j8&z}c>!Rll8_Ml<$|>7IJ9Q9x)lC?Xf{I8YrpU6@{V*o$^sSuAb% z`Oa`}C@Nc0;!5_{AnJP>97Dh!8vvL-;6;cqmC~eP_*zL)S#IjRuUeo_fpJX6p1SUM zea0|!mL>al`zKjE4$~{EPcf!+q+niu>xnvQV#opk6BlisWgz~Mo%47SLEsi7QeF>Fmv9+jj8wt<>gGTj^blVyyda_TAt z(lN&6@{};_qO|cYrfeFSM0a#;kJ^WrfiNZPHshHvfg&V0&rn~;%3}kJ!Mb?NWldN7 z&eUE8mhA8v-{#JUznQ?W|9(!WHLHtRlXWVJiWbis?>-winKFC9KXB)^bkWNH8CJdY z?FK?)JCMP%8BfKmu9<@YgPG1l5MORBR$bPo(|s!wCo1M!uBRbdniyi~E}?CSSz1ak!2rQ0)7uGo zpJWlGWVYyOi~<-0Ucq%VsG*A`w$If!hmGHT=O?IV1v-eCg?!DZqALLSqX!Gq<&&q% zEB}CQ-uxaXEy_FPO<*r%d9|#y_f^by`q@mk{cfXux#x;A%CcrD(EL?2!~AeTw_i^+ z3;1H-puZR~be5NzCZ^@Ij#LMBm) zWDSwYLR>4#ld`>LO+{X8gNDs$SreucoKh6C(BR??0EL&rB1Pm;`NeI&ivorWh=B`Q zZrW>DlvB&VX|j~Fxka889n$gA$rq8RW0$f9YlNiHh7;Pg?MsUUe>>pA}p{YdaM`AbgjB| z;iFeH`G|M2iWF;luIufl^kXB?#sk(HSwj(TZ(dDyYm_1Rsup=gu>|H}p4dfstvv!k z6X@LEa;X@S9G#h^>|7(x90X*hTBet%uevr=i17;HRMul-o@+A|11z*fOdD*lsI)Hd zOmpB`63J*jTvllr-urjmDPR0#*W|PJx44&1*pR>sHy7R!0t$pD!e6#--w)7n-GBQL z8avNz^L^Z-A^#9$&C*1-V63Sy{5s20I(fB`xA03-3hG9>`PW>i2^d|P3 z=~QN$^+jgP7l3EF*#3C1CrQT-WWoOKnmDt&gFq%c2qvWjz5_HX5cKejQ*59!NEmZG zt>Z~5)0J-v^l{$r+F^V~*)G^j_&^7LUS}#C3rHVUFE*qC;6UpO%QF zTu7F{F@xjSq@G`@JI-bV%Ihs6M4Lc+8#A6Fw+n>hE4ugS<&`NJ>b{QcTRhSzoO|p2 zhLHh)8rK__ToTaM1Q#BCH}n_9+k4+90YEJKT`OAMP>Gc^1lK`{C3Uns8QZKbOXc9X zrgDAa$A-G|B%wVDy9+J)@9KpJ<;+4MZgX771BNWfFevo#_vCGvvTxw-+xp}>3YzEl zs^Vmd;$J-8`xB)Ns(Sq3 zZ_;2o+jetgE}^W@*vC;9q>#Y!`n{QCWf-hUih~v0cWN_|ea=BWJPPxC+=%?;^p39T zmM;6;_5M3b8s+i)Ou?kvNa>D3GN8oZJ`JXeU{gYIa&}mN zC#QNs0#I+sx|B(ruZb~)pM$a+- z5fGSvHaG7Xay_EecU3(j+!L=?AciRn#(iIU6o7%0@MqItkoqaYkb5w@i}n1ZC&xSED46*2ksrEJxW-Q!?YSDuMp zn?&Ub*Ca6?_oc}{tomVKH$J~ChTuQ|ITQM{i5>htCSZNp6aa%kf!I^_F zSy%Z6HdJYUd@Ys0V0sJW_3oXE4XfzwMS=il!GhQt3>ks|xv-y8lE3C`S)tw?x=3+w z$^R$S`tt7niH*Dc2DaujH(GsMTJ%J`2e#uUzK`zhBS8#0uhWd93F+Q2WkIc}uUABuI*B6&9xdP_o!Hf$~xoDW+9JSyS=Ku92tGQj$y~U02eS9BN zWqKEm1{#-RJdgS4KY-h!>`6z?rDr*gWNn+Al<2=?-&fXGh6~=yDb$M>`OP2?RW223 z9EzoSc(Y}me!c#a=hNMi>VWwkZ%YYR1gmDPjb+;+T2@>IFs7YB+2b~bWRyvrR59mR zP1{MqxP@SX^mc2Hv3OnF5T$^XJJ?4H+QNevh%A!!go^G!!q}#)_um=qx@hwi+cXwx z(3$MZGX4!Qgaw7tARPjkAty8VHMn@D*2ksy-Bds?909iD5cxdW5~qF!+)1S*33L-UY^g68~9y z@geZeQrle^-7?gN4qu-j_qxkn8bL1Q-^$>`e)7Vdt@d;ED9M;e6oBZe%u$xA%WJ00 z@urVxC_jW-pgGyOr+z4|?(z0{+Lqy`S~0E84+DeYsehcazW96Z;DiB-w9^wzkSH(! zV^eH$vOs+MMHhM%-L8!=A^0%&M5F8!8@z_z8+fx6$wRZm;{mn;a#Hc#qO_RHJMnZ$ zCToqY#Ea6t{t7^2@S@Rl=?eXI{<#~UZ?9=f1%0S`emlr|o1W*3;P#(x=uqWVSYtD) znezT6vKOzn%g0Mts3F{7CFdG&+1Uziv77!-d`x#ir0Tfl_KAZ>1ordisamHPfSG-k z`K8e;#ED_r*njV27xvWh*|%aR3a1@k+QU|h{~kN#9_x@vLoBip%FX0A-5 zaH5B4I;_tr)=pAL<$pD)XAkV2>J&BKn}U{4#+b`6wF#Am92*I6?W|&8u-p7H!kl1`luIk z|8g_ETLYG#Vn8vkLXlm*`8X&%n>rH;Z)&I>TU^-3BDb=HY)UQZl3?a6o%E$eDXq^Jn9E_14>Li1Aqsxlv>`*h??_v!y}53&~4RZ zD@FgLc?-|^XCn94wJ)e1Vk@0>aeh$b_)RirQh(1gF~#J8AV<5n>HHJ!iOwRZB9V^1 z2;>`W8$x=9v4!$d6K`)n%Q*L}IBeE7ViKwqFn6x}O?p=nA?jpzHo4s9AxWUBvwDh7 zJIM4RaDvARsp+iKKyv^N#wfkY-%>Mto_D5~9w-?Ao*XIPw|ISvoFV5GxUkJZSm64N zlwo1~F#h?t;(E{8g_Y@DX709U^rgPT0eG`Cr9EEuvlk=zTvJud!JJ-fe60t^lC^7< zoraGZy(V8GMhFgayL{#YQ*z8kJ)K@rPEpC4COg)hAtYJLx958_=#Lg_hAQOlYLO#JzwQZ)>wW>06Hg*g2pBKVN`ZbB8`k z+q4OiVFF`Ex|lp1Y#=q*Md6}37_4WIQpQZ2^vvq39y~(70IuJOc`_1_`dAz5pfw!5k$v7}DHmYARgm(! zhPGTxRYo}>f_-SOIsiJQWl9Gr3U;h4x(l0Rr+(IFb@2(h+>&pnlGH$7w_hRAjM~xG zp2m+CjVoXw5^8bW(Z6iD|9qc^fxS*UwfQc0U8iF zqU!ZUQyC2Z$pi-=)G$>?4x$}rP#-kU-FV+~?Cs~Cy5j)eLm?%C_$I>x`ZCOpmEtnN zx_!7iIC>|zm&gw5CncRkg5jNU4CcU8`ACfGOCJKV0=$LA#ly+qf$|6d1~X%?X-JzB z&kGvEI+K~-jeDiO@mL{wN}7g2?3uSxU$QJL#R_x9*cH{OE}vabE~6Bh?Lufwx#lxo zYuxf#SMtaooLukIn3s8V`Tb7Hxb_-O#R=W%4~&H}XL^IP{E{ay9fyibw8V{($}d-_ z95qhn_K{Ouv=ffzQHn&#{XQ1mkyN4&55k~*XIX({pPX%-JHh=+5o-(hCe-e3tZI_Mz4?Q(;kd8&kdMNQI9y)PyDV&Jx zgbUiEk^l%Gd_~nt?`?q-1-&8uncl_sY9tpad?bj92p&DGb`EVbmx!hG1WvQmjM>tA zP4>vP61RsyE}I?NOI)?fU5EW5y$aZgHg0u0qx$kH|mMo<-iZ6kZr1grciI~2Ji4>Lo z3)V<{8RXltDmshRps}2n&n^k#=>6wYDS)X~=wN4$@xNeWyEKkKq)*ex#c85qHSl|l z%Mmf6<~k|&Ow$=W`%nZYgbuxTftx}84q`4gn(^1=$L}3*gNsvOZ781nRsP(w9QZt%>jQiljh)(Jc zo3M2(1_tz4*e>$88?n@0MMA8zay>DizQ|8*VIjXTO)PyuEJY@n5W*xDe z%ubDuTvtVMhpq1KvbIfzI>F@#plbsEf{gO^55;m^cVCirT_LbOb15yW!*BSN53~cu z|0>WQ+V!%`!xAiELmNE~w7hH;-DfpYmPFqIda@4_+VKQoegMCJ59pI!cD=nDD8Uf{ zh%+#0{;6l8wcnSrQK)*~9OGS{LkcXjm;RnsnnA0XJ^ua*KhyFk2$lWI`tV44W?5Fa zo~kx&Wd9G9JDr^68DA{DOoyMgi#%a>4F*U))jjfnl#u!og4O2aWnb}LD`+Z@>Hvfkg$bk zCPF?~uiR*hg7RV##~MC_c&9xnyB=)7D8m9Zr-R7h$+JX6T&nr5yJ*xLN5c8!{N7&q z^ODzZ6UP@Q2w>D{Yt<5>qI#Cb3{hh`Y7eMBJS8ag{IHF({~yf;?pNo6qReoxzJQKH zO$wC)T~|#1*@KRz>jdiAn<_P-B&cW(D1sC3YwluWBLfAV-#ez}X;yqg+Y zk7Xmr2}VAzmWG-(6J-;rC}T&Ktz=96)Y-1@t4$eCSg{3ZnZkHD27e2aZOE!%mD{$vuW z+5NQ#z${2XMl|q5X3T1_o9T1A1~s;>$j{AfSY5gz69%+`|m1 zH9_jdMZ{^M9ztUl&bfSQ{5R$#s*a5f;y910AzX>ON28iT*=v{{I0man4pv#*xY7>z zmjcLTh7B4~BkO>pF*;*>MT}{zmls$uvd{?u0U3A4LLj^V*~{@6hKQl*&tQ$H_i&XK za&hD=$zfKx8J;~oI_w`DTS!GF;;1T2U~9{C@xIfne~2E$P)4C-WaHOp=VMVSjFtDT z!r&fuS$GZ<2A9s+7WT4%jM!wyc%F2~%Gq_fQ_ii9UxRnqH zHjG3*Y2XgSK)Kn0}3voegxOT*ic|p534M94j1AnV*~US6p6~Eifi+m!pEZ0kW4g7 z_pw#8Rggl6+J@rF_XC0lw*h9BRGWw~s9>6|FB7Rzu zJ6@jzzn1{cf!8Va#5s&9sGIIKaz08EKekhy_{Ov_(X{z$Z79*_Vulq(R!8T9^tS3# z4{P7Dr-Gh2Ux##ox~?K|=r-gu#%Ts$T=i2e5Vq0ZXB$6{%)V=S ziF{P{r+H`3TDg?*eZJ#dX)Zg#RYnW_wRZ{ASbn2oe)qbLd$R(A0ZK>gd;g8Axaxk- zZd{F#UA+B4?JZtR%8CycX((dZCOJzTev)g}xU~Ef{HI#XKPhhKviaa;D7+u5ohiUE zfoO@FqMWYXP%MSWE2TMbT^v%CjZ8I?4KvHIOgoPx|!$0vdG~& zzST=gv1@A>k0ux>C$j(^!F{5-vzS=U{!eGHxTz-L6WosX98ln^2}3y*V8RS<0BD8V z96MrA4>@%a1*~%(W}f)5AA)V@dl;bw15!GgzgnnQx=G4xhwq9Ro<~pd1tc=(I^k3BQzF$3okMh7<~u(R5V4?p8kZqL^(=;y+=?bW z<+--SI-*ak-r=9Qsl3`$S6UCwBsMb@k5|#^jY%s4q88AZX6nv$$x?S(i^tk@al2ky zwWIo)@C*267;P3YuZa>_%1V%C@ZL@3MVFRXnKNCq~yktl)WCZ4m*151aO8KkJ+V zOp{U~n8@^9RldmeUHmxXDa?{ZE#u6R^x5dAm}^~cy85t4!24c3+Z#3*2zKLfkhaA! z&;N|`2~QHY|JDg$o()PbhW&f#*ZmKe_iXn3;Kyr;ScD_EOG$uHw_w~GIZ4Z)QAb!} z$=Wj~ou1_-k~Nt*HcZM~svf7R{k+o1;5r230_c!o7B|WIkKOVe2q+;8Q#+*)2C9Je z?EUy{q@oJmBKu6IkNaGXZ5ziPS?6n$q@-Py(#1+!;ZoB?U_yW8Jyb|Rt(6M-RN>b+|D`> z*@bxe$bMDO_6nPA{s6??X@RiX7@bINW(O{`Vi2pqg@iaZuv!#R(%JI(TZ2PI1gHSJ zfwfa@ZSNp~9?Pg6@wyfs=d+xQt(&(`Gra zvsc>5c_#TAo4e|tT5L<#=#g$N3Q5X?8tDG!Y=t-LKlI_=9lcg1T`0L4kob2q!g0vI zimhGhpTsXF<9_g-+|!$q`C@=N7_UV(_03&de)UdON}iAn5(z(b(m&JT7!j&k!#7=QB^=pY7w5GXgj(I7Y?`6ysn za-e#vjkxYkc(-tk#K;RUof$f8|x$_UQeh|aTKobE2 zEPe(ubda_>*k=8?3Hu+}S)Yprc()q3sO;#xeI?d$iX*ySyM_Q)546F^6N$<53We3C z+%1w>Zzuf~$flmR9g*4kj2l0bI!1Z3GqlxljKaSZ_LK31)A8kNw2<85>_e5Nc0{x= zd4^o=Hw>QRekr`tlBGNXYSA1CSV5)B_uQ4+$AL9kJP6!fUOXxWrMeX$UtDKFMUow?aEOsHoprzTnwddq=Qvgr zfgs6F^P*$Le@JL4vIT0`>kd|GlTTLq94a)8zbBiCvr8Si6&L8NqA+b+r2ED0GE=jY zQb%Vkcnv~{Wg-GQ1UxqTy&I3tSsDreD+#DE_f8Sk?*_epz}NqiHSOuH~tpIW9I*ApCkvcp_)puZ`hI2v5K zoI^CA^admf53a5!HeJvC2GnXl?=|N;r()j(t2Zr)rI16@64(if?S(;}k8U}${Q2f-u+sri4xBJRE)ZwE#XCI|SuEPiOf9i`l z3pe3JjdiSIA#dFjexIt5uiDIQ{5{U$CU#nxULV8nSnbf)m*rC{;#p^DQhJODx)d== zSIOn>s)p2@5E~RafJgvr_pd}dhd_8>W?OeC4S#~@N&eOZ#W=UE{#3C)l`<|piy%(Q z$pRj+ulkQE+g0Zy~IQeMoosPsA_;7D!Z*gQvOif#9n-*a(1B4C`t3|k>VF^Rj~ z+AG~eEXp*{QdicbFf{%r8LCDAGPIQXDJ=I@27#YF`~0o0^xVN{Y;mMe1Qc-LfP>H@ z2uu_Nb>pA5V|zXBH$)8nD=g7`Mcc{KTTOD`cK-i{fsGMG#0UysyZ_>VAP|CR0pC&> zJzrc3k-!RV&;S7`SM^#~UN(yX2T|$Ty5%&a>hxV|duk2}V2gg?p7*s~vKv_yhUY0~ zLcrs$uitMO#JF{l1j9yE`cFD00sGXEHyP2))yOCIkF^+P=Q{R!94!!TgwlQL#qWe` zhOyZ4%#+wj%v%Z6sa06PN63|p%PERyNhsQZ)_?x;-IrA0 ztlmnec&U5r@@_U8Q~t+=uYq?L@#y~piKwCmaVZJ|B@jtO3*r>3N#=q#kZ8Fxy1vLnwnp@7J50W}U{y?-?aa%M*7;ou*T!n&)Xt68+!t zOcn|XV4ZXp9F$(Z{F=dm)2V$3sqQLG^el@54L@`E_hA*Vdn;Y=)U!uuUcdrDsCLPi zw6q!;E!u9367EP}*T9e$Ks!h|(>dosdFR z%p!GR7q~nuqxmkk!GwJzXmS6V2z1Vn-JW~p1Wl?v-rNOYZGS!5bcdsJFsJx>{Q9i- z6pJua4%P)h;37Dv1K5xrP1%k4kAADJD4f>s=$Vm3AOoKcNCN`JvllNgFS-BTwzmR5 zLfEpNk&5jj_j8H(?|=IldF#|UCkz0e9;7#``?BqSHZNF^22h_UPj(<&oJ94*I~pOI zzSO>NjGb!ye+KWcQI2o?~pRhO`h z%hW^J={yuSS|zIh^Ohv7^}rSck$JW)4G!T*5!P2_wIeK={&|Vr#r%VFLGp@c*;x93LS(DiaQ|VZ-uE~R z`6kvpDHku#AFy>~nAug#$Pg%lgrM*;8U;)`x z!}=G4o3epO@oCUHQ$5*f6q*tGE)t_=!cho7H+|9wT=+hfC<}DMgf2^jZ4QC}Ag zrh5X=LPjBp2Uq-AfTMnmSg+?nn$%o#p!>e^$}1tqxm=t*o;CO?jM`zfbqpVWV!RK3 z3LcFGxRw7`Z}|nunytrVkC(F4O59*}CjT|kTc))eolCU@zni7V;PAMLaI9zTxW%== zBnQg=7KAAGbErmG_pbax!7A|uyfrXiv%_09hTH*wl%qZ^Y-eq#}($l*cW=wZ!3VBe?KY8ii0!eV9VO%A15lq zVYwnttV-i&|U7n*Jca6Q!Dfft9#+pwGuGLASOsfd8oXL|i4-m7W&g z{zCb0a2Bqg9Fgmr&YZ^EvuIrym=+DDWZ*C5R^J@kRCb`xEOU0~aR#q73VN2oSolyV z^^P)je%Zap8Vp;$BHg9nf6v8C3DhvH(ZY~^qwN~kLJ$a$@)Km#d@m>JCDmFw3Q`{`cdh&g(CMudAd-x-T6VKHEj{B zTc*u{wod2q@?iL#F8<_}w2QT1#e!L~se~C8UI)_uA$Y9n1orYJ%VU4QO)QLbB2!Vi zmkGu%6ctB#DZVR;^)L{hn`MM{)1x9hSXT2UlW8=XM2j{8i44{CCB7*dDmfH=uwVrO z52aEYOf^0pUv31XC6Dn@8(nDnHlU6>ENP_j@|*zGjTEhd)*t6~J=L2(am*%c2j80;5@Q z6C4!!Y&WNc^Jd3R_g*2p*(}*3yUpsF?sdq@HjvB}<>V`jB+t**)L`wF2i5dmYrXmK z;SOEt^v%e@K;E+CX_~hZCoxA0P>2JNfEeVWrq=1jR|);O+=B|*M2L8U|M)Kr^Q=)n zN{GH^8!r5hTIe^e%OSh@CRE)N<9BR|-}QQ-d+HkmeL40!JLof4J5AE$S<%W55cEEb zB_+D&FNE~p=sIhNNmOqQ5d(DG=BUdBQ&zKD*Vc=hVOrw`h%NhJ^RALj7_Ob_QwAcT zRk%RVP(v8{C=}mc(N<)Td<#OEyj}K}p~qt$!HYefzlS>k+1X@7PbQ4)qr1%FG+oJP z`=?F4=_74rBBT%E772b=A)*B`qfSxEIRDj1<8vF`8c#1gkgk+r@m_u-T(li$d-; zQJNDW&X2LL3Y(EJD5N8Txhl{+0WGW>l}V162*(7D5FRRHKeb9G!`pP({%~JJ;&MYO z9(PmrY^G5}`e$c~Q)5|q|8y;t;w^Xe3Z$CNDe#drU<;J&!`D11RMZ9q^>Zbi>0H0CBbsFccm*FH2l@fmw)g%f^C| z^Cdq`R9x$IvFUx<;c-01cg5uRj<0NXKDXO3$$w@k#byZIGhxMDMm7^~bf<|OqHjcv zq}J!CZD;cuk>|^}Ri9b?(S$R4FW(G_02%g?g?>v+dpP}LzsP*OREL8YRsezQErJLa z;Rptt_wbfxp3r8T0g#$dM!R(79H*Z*TWR2tr1DeSH41&@oxh)Sb%g_MnrGUKqjx$< zCbg#8c>hvy%~Oo{pqxhfv&T47G+u*#uZ^jpRnpkm%D%F4m3-j2ZaX^}eKK@LI?K6| zF<%lG&Mxx@Uh*`mNEpU92gh3IM?+w({W}FF?l_|&l7*ubNmQk%E>0(3LOk!gtJz(I z#`a_qm=@FG#<-60b03M!xHwi%%k%z20U2+0x!s`Uq<^-ldjdfg^VTMf76TlI+@_cT zU<4PH61G02-WyyuLi-q;@{W3>h7xY{oQ9frG@-hm zb-}G`Dn^Hi@$MBCFeW<<==D5vSYJrP4oB*=PBP3sEA!OzGw^2iIQ=?xUMMQS()he6 z{TBgtp#4!#U)JM+`a(1UI&l{EV{l|6jIOYB2^$a7O$`xm-O5m-*d7~nBuY-AHa4t@ zm-y_8SdF|MsO)pvKHJ<^?3fXu0K_yHe)xf!cdMLjd)#)5$-Vs(WFGS!h4fVV+U5$D za-7AT=R1fx?@KZ=GUsS4C^JtA!t7ZcZ^dD%269kvUQk-G{v))*^1~81gE0*C@k|e4&8Q+8qBe#I? z$9yHNp>l=oTrzQ()nU@s>%5Nv*XhZ-3EZ6iYu={8Y9W6UiZo$W?pH)N)5x}LIB4l= zdx|g&6-~KVml4guG*;8$q_c3gWWR9qBf0$iblgsjzNp0rPuwf=EyK-jUDki&l} zvZ%RFBiC6oHr7f{rz|nu=t)`vDLFM`=}w<6a?Y)7)UQ(hp8)RUu}QtVUxOlK!kd_A z@6v+jDy&+@Jp2mtrOBz-qt6d=LJ;SS9#0sF`(fqK;gSeIn+r70=LmssoV7^Env{H~GE6)jAWQX1{M6htX9=Afi_>waF5B?^QE44ZdG0Uz z*wGfj@&C@(n>lSgaQXr)-*rlxY74f8f`^|XjKSUPoscW3pnw?Ktu?}_IW{-NB8lZM zT-PO*-s!^2i@|d?)lfO@2eN)DugU6)^LH9;J-p1qfH=)-2LV+_8(D@-K4Uco5N{{B zv}LdJJuxSAt8kM8@4X8RsK!^@~)eP48X2yNnio2}L)?0-F0+0B?1P=O8~x%+McAh@c5 zxYV%$!6pT34CY8azr_RGz1hQf+=P9f>NfDrdF-|(x8we+E~A37JzRLEHDh%=l_~cLVLSJ$!&CO2^Ojf`lfo;dV>xI?+476=RwAn@ zy*^IMzV;b`#6qFuwhgP3G32&!2|~kraryJ#=kA_HA@8kE?-<%h=8?_1xWiX4fF1+d zb?b2$gPH<~0Mcg>!3{A$(^V3M{rV9ifA3v21Pmh6F`AS*mB0Bp#^1#8_NQWQ_dB<$ zy;GLK-SZf8He$|ws@F}#*TAj!NK-sA2b$suCI42R-L+ct zN6Fcf4I)4U?1S;Z1KKP%$3%XR?7w14cWEy@ zpPWB;V3lN&loa;ZMlL;|&4Dpvs}hgbgz%XT$xkK`n|`uh@$)c|N-x1H2UVCC{A{JP zc#PI)5;vw=jGNI*rC2A{`NgmuzE&fkoeajNkcxHdWB3?B(2k*l3(9~3n`?Xa1tFY=lnPIp7 z1HVa!GIg6fj+-Uwgo`%flatb3$Q1;|quf{12Tb+^IAdZXnIv49F)=+dh?DVTE#@KETa`ljagM=}py4q<}idVicE zkadmQk*k25t0gjp9fxDCX93w^eh{XSxdDJo(ntjmf2g*3qP_#+;U+-08?v%lyO&X) z!TE?^^N@ySI_tZle}6S$IBd-0|Jjxtv!Wmml!{6*KvR(y?LRG%1ok>?{`35oAQoEL*=h#<%?m=ICQt>2-oca~XFANvh*iKC~R~KCinq zgB#nOtJ@o`o{*7`+saHWM zlPDc!(OgMG3V;EC6dRBCyCFXf=%EnwhfYvlo&u8FwB(o0VcK0e)2*6HdzSA`CE#t> z1l5_rMxFnEpwy9ZD2r4=7p3KyL;~8Zuz?w!e=iccS|2(Mr;)2y|7Z~rbrP31dHJ!$ za9QTBLSj_YUNK@Z0v!T%FnTh0@B>y{TJ@9}=;Xw-?*qM0kx^WyE~;D%63_6@*E-Sv zT|=NzzI+%zlg3<#F(_QJ7FTXL2)8+})k>h$?eb}M!v3L7wb4Cc3iKE*}`2M(RD0;p8BdG@r$Eqo~CJ$hPdnlua zmogqh9nMA%PjD*dHFS*|37q zmUqdHHO!?exM{!vpd+Y4{LP&!3|;qw=aARLTAlw9;$#ao@s@Q=)GbCc%{0ddSQ#!!spi>w6k~jlmbKf;C)eW3Z;)%3)trX=U z&0o;T97>P(fv6#zQ6w6R{+j}Bvc5zf3^X2ZPEncDi!3+hNQF>bVe~F&o0L89p6(-i ziPEZWjAa5^QQn9hZzh?NKEwHge*sXDvxjwi*}T%m{?L2}!j)FUB?xv}iJ$T3k!r+T zI%xih-e;Hiz08yTD5*(1l>Ih(mNvA}QB@CRm47tV6WuR&-co_E{Ack0Q-?A5lvflv zraw)ESGpe=k)nfl3k(yq4!(~L_urO#PYli?rmc0~|6|Uwddbxb^+G5w8Z*qr2AMwT zY9KbfZU#O;M3obOW0WzMH0KZ$acK0s%Rh$DnK-#@XUsn%L0Ro0z8+&FnpVksukYyH zHRd;5v@qm^d-?Zb@}xM8^^=ZRX3YhBx(P=xGL?Wwkz;i zLp8>+XFGcD`)_G*P)axVd`n~^fL^noD)3+V`yXIE1Qis>u?mKBL&UqGOr_F5+oviu{Dd2YPS9JRJ7RJ}Q^%V0nrQGX9l+VhT=}b>8ALg*S zkJk?2Hx4EMIYWXoohgF|1AF{~Ek_`u=QzF#M>Wa%k}mf1B~tWU4lBoDU%_{;2=`WL zwUg>yyCUD^^l=2EPwVt6Ft;~P;;?hK@@&T?82mb;LGo{S3xFnOO3$ch!8%ncrL6lQ z@#+wPh7vBTp>@5>>-|lPAA^q@9L9lQ@&sXQDIfY%?h7mmU%v{l~N+nkv}vF{Q~E|0?$M1P?Z1DHl8 zPkqnH3=j}NxcNG9fO>!3;(x-&B;k8?6X<^~N>PyB-)GyE`?|8c)orfV9FE+ zKUX@KpNs4$bzsbBS3Vw>UP1jtbc8vv);&6;<@SyR$Jw8eLo6G$(J;FLfkA$TRXxJ{ zG0XA46e<84NSZ%i>k(}^z*cvC&HdM_h+o4kf=Vbkx*^-qrW^$WH11D)qKzg*_ZM_lnbC$sJX&utLnQabw%$d~v}pSaM54RaOWKE* z1KlS;_QD5v@EdOsmfee+>ZA6PLLp(y9A&FCO!&}{>}a&egCHPC1Q@mohzhMZBM%`@ ztg6~w<~8to6NCRt^Y!@PLb2-{KfB~E(EH@(F;t8-9l=q+5V>A_Ga!wd!GTiK>o;8svl~y-8%eCy9|J2f7)t#w z90$$_dtgFR1|l#aFNN^7;r8vGJYMACGRI!Cixq24lc#Xl$jfZSBY?CuWh06b`3pGK zU;(+HFoQVU`jsTGe00HwTbp3Spr{U{4+i9An%@&a>>3&sHaCAVv*TZ_G#sD~1|)I* zXu<&Rh}5;ysxgA~b3@d}vB3BkKP=O4+6RX3B|#TnV@rU>ab98J^9RLt08yA0>e4yc z^=UCs@2Rr=DE|$Qsr8Zm6E)$n*`@^mm+x0SY52!b(B9P{8)9tWkphaqNM%Z~vn%-i z4Hvk$Cou#;>MU=qc$p}$4F~{Z5~SCjs)N*{cF$3~L0V7}hY&4wapnJ3dgd5#D|CMS zv;pJ1HRpzYY}0Y-SVyC{51d)spjV$_wM8Cd-UMDpubxV*ov;k}cjLj>a-oSf!kH!_ z`rYrR_3q#KBz>0P&;rT1dWL|&!*rd_A3Beo(gmQC1PN5IBED@G)g1}@siKQWt1XwW zcs5|5q=ALnNy1d;PI<(gPe+0&xFJOcH{0?*4Okb?ZDfutg?<0EO>U*-e-l~e;h^p1 z?rEgeBoLJ~*1)|HV88-0+x+{6YaHg`-r52L&V{EbGU!Rwxzw6ApGJPy^IzvHrvf#O zH>^k9iq%<2eZk%+uc|OZ<;xm`uu%J>ab2S@y=k!1lgEj~cqV;C@6PYkQw*5tJ?Nrl zGS|v8KA9<0tiW`N18?8)`xFAN@aQAfuDHN6Vsp{6w5ZWL_dcG5568g`v00_0|9?_f zFt(QR1imoWBzG%OC*oXYcuebri6AMiUV+;@oZ~S3%1&dsZ62I^85eO0oS2U)6Zk>` z^?aV9xrYi)4DET@uZkzhw`8f{J#oa}%l}ACf+BiA$bAOl&2HU9Yn1t)qZBRce`~0< z_(X#hotT(R=3(S?C_9Tv|dl&XJx{+EK`@Ux(Q!C^uG!TMG4e8E8i0%8PjW>R<@TKT2U<>b9#CZWPvreO@% zw%RADDx0Vj)_uz{X-m0KEo}A)jhh}f1#?$mEb$fNmCG)-D*D}fgD8ozB4aD3h9MVA zT+rTbON10h9w)o2Ut#v|CMB@U@2+scw|#&j1$#;XVl1o>HGcK71K4d#7yks{ATc;N zq7VL$NCS{JDC`!k3Nt*dIOd#H2?JflbRf;(S7imk%Nwj&d=$QUCX*D2-H;SSzwUI| zGjX)O4Z3pWxCeD7c`GmKitj3j@?FL50Kk?~Hz}wKS!j1K$V-^{uqWN}J|-KAOt*7= zD665+nG1{-Zbplzr2c6>y0@ld8z&I#qz&i17XH0?ye}}ZyPJV^oZX&yVo%Y5c?WM* zW{S{Vkm6n4r$H~GN<2K6$|f%Lmom~-TC_fRWQzJU?$}aNw|+Rm*59oTt1tlxU!<0t z1S9G(WhP_C?-vvolgZvZbH{2t06Ay|fS@3ATWAxFd}!P(q+N(jH9zM)GkW;`mm8%FE=LhY?JqCnCLuB%SFosQafVWl5oK5VvQ zL)*R#1t?DTVdeW~7&dhSJ0UAXjNq)>dGS*RU1Ybl&5VEivryJmXv*m;zQHB2N6dN$ zIY+$+*h5f*MrwUAL1hN9#l7Jr0LZUMV3V=fi6mT_irYZSIX>^MQg~n>f>s|$R?*1U zjaFKiwzf_KJFnEymU${y)u$zKoSa}tAsvO}qKn)s)-0UghzyxFKAGEE^z|2geeZ&l zXr0w;?GnzQ>m#3{@jdzzw%m;?Z!ForIBmc;IC){d5Vbro1mKzZxt^BzX13i_QmzCC z>L3FP=B^0Ck8zRaFsa2*B-%GN49W9reA>$*!!^G?pK=GHUboME&4j*XSINq92B`z3 zD;iNijM7WU>{*EhgIdJam|Af84MjmY( zI^VQd#ZdQ*5!kJ3C?+Y<=W}}Nng#J0m<%g>96@szT`FKEjs#!jc4s0UK839?{-2+Tc5L%Ey}cx_y-C5B4Fj$W!*dGZbs1pQn60!w0+?V6%}5=u`pu9R z{rb;dLO*D|-)J`D=U;aV_wmD?&)!zn+4Ox@%*GbVr&|eq~Ho1%cgla6hrneb2(6c+HgYEST)Iot+9N zNrB}E1OViQekK;IFlUz}9l+ocYu)lJQ0^!1WOQC`Ic>|@AeX~>d4qyPH+K=hkg9uj z$%*F{ZhaNI8`^+B-8*?B=I|zvWaHUaE{!kZ97Xfw^ig&hR>Cp6^mDtc+VGHjxcrEC zMxAFI%3S4gzH7f_3_I+i=Iah3Q*FjkaB;X?Dtxf|3tHiZGa~~hk2*_V2!9O^B33{Q z(jFrNr>x(t#mAPG+n~&+*d91aPLh;KZr)!+yBFBiMxY8kR_DF{w#icx1qk;QB;+Ie zcXPJtI(aC2YkjxTd_L$lLFMj*zv8?Aw{Y+MMCruvAq@~Ec&;SmpM~c8JKB@>>;p8N z7nq<1Km8v)OOs>kV9eitvPlUcQ_Pb}Zzzpz`BjXB)?y2mWYe&PW$F=2Un8Y0{Pa7I z4B@$AfWP|k2=@&Fz(4_}L{5xED@@=TOCnABH5qTJ>&N=thUMr>VR#ybzZaw8lLo-j0Rzix_mL(zp31XBAqnsN8)dZuhq# zV_m5?hUc#xta-jxQ?05Q!FhoLi>C~tp1{XAL!@7EKp_Mdc!1NQ9cBk zcJ`Zpa{tX3WAi3SL_bdMlK~1M9%x7v+{;A6f9uQGkl>jNG8t@Lh zh9JhBj_Zy~t17D%^uP(YSj_M=@~4U$Hc8diSiU7V{{7$2>5O*%f!OXjv>!9+opx5* zg&^gzsn06c?FN8Xi^*rl&4c?mrewrw3Pq9s-cE(Nl!QkuW0S zKj2p74v;+A*DZe|I9~7VcTlZP_k~eSMoL6p+<>Pw$g|W#vy95o{!-ebbFr|k(BM3N zXJ48gx8fsa^y;L+gkDm15tub8CyuC>f8y!AF%`*kD)1mF%YWt!Ow!{!MBe{`l8WF~ z8mvvhnIA{P#W-GdgV4A`{@$cem;N&aJjMq~C!9(}5S&+5T}Ce#IL`uq40g*yi32dO z;-r(oY0ap%ypknCcxWSmejEwz&Jnj`eB{eKHuGxr4hKddSX|v)Atv28L>K_93_grT z&n*g+9GpMl%fPrm?QUMH#Z`ug1vzk{gWZ>SU_90Q$*nK#QX6Yy-IeryLlarm5qsk7 z4={p6)NsEX7!KS5)u z&EM%g?X3Fzek%ck`u`e)5kjQ- zvuY2Qw8*2vGpuYlJYnprn~RQH+zq67@h|wMF<)Wb5WHQTg|C%&%5T+_tc6LK5C%V2 z{_DQh*tPGe)u`6#uexj+26n5scz$i2Sm%NBcu^-=>iLihvckc&scBmUmF|`ynM|0-r;3<6 zCLf%ZTtRLR1xD0sPt^m_#UeQ0W2g1J+=(vxQcEC8r!(Ok6S(>pn7n-O|( zXaEBo`#nTc0B#_S!v^j;Wa$BA9h%~DgdDm&V<w7e`$I(g8V7zxd@*3$0)p_)X{j6^J05rS@91tv5!1`=n=7jdXEwB~A238f? zbp0Bs*P{*AyjoW>epHZk(MG^ut`<;8Taqj{?p~}115|VTjS+&QBw(#M7no%{iZjlyMsV6JB2ML@rnXKf!rN^C-x+vdwqhbhA?L<`f@Hq^MQ5n zxDE-CH!^<)28r#>i2sjSW7MROXY~FQM|Jk&ktNI5!Ej*cqpp3+Fo;=2?&~nzC?r#X zJII$%2@^7oFa6}MbEdt+M8Xa&lAjk4l0Fp23?O>i9Z`Z4766kMsHn%dDM!@pb{=nI z>oFn1LP0A9=SGnUn5uzH8ikj6q|^OxJf!mXrqJ79zZapdBVE=zO^mM%C87E3w7Stk zh=}GAsW<0vD;ebS%At~fNt8AQN%2N1p^t$@I!_!^Svx<?rW zvfM$?ow}u5M1K4q%Vd{RY<~hh+7KySzl2n|ie~AtgQAU%?G*zTzin1fhw=oKJ|A`` zt|3SIf}2UDH177X_vhvW`IaJW*5GhTLdr!DQq`PIqiXq+(BttDfBGqulx5>>G^|DS z`R;Nf*vfy$g=?1m+hN`FNIyO^zzTV6Z@dWfZwI@ko>l_&?BxKVP-6(=F=G2q{=Xe5 zac*pvv#N6sT}c%?V>|Yv!oD_s;tn?;z&HR@YIWQXbM4v`dUH*~BRbIxYmk#A? zhk4X1%VFS!pLTc2UuFBsF5hC<7mUPyQJC?<F}%ch>ULjR-|HbJ@l*7QBTKgSrtQn_{vx!`2WmJRyotjf5gh`!P)KUH z^Y>!O(!tPaOy&TzLNU2sPE>YdY`vJAD4V~5@hG?a$|l_HlL33h_E&gTXK>$EtW}_! zV_>MIVQJbo2iw+Rt?MZ@yR}Uv?h7INfpdv7bH}AOuC4EJ)7BX3?3A)tHEwZ=?n1j8 zqYaTJ5O-DE9G_&DIY_Zw`D7MAzgg)?`M8bp$AgIjwp@X$1~@=Jo#e*jojcj+&%Ya? zsZ54nLSw1LtJ_S^AVmc`}+#7b?VW@`_9`^p2Ut4kokyPeRNI)HR!xY&O-X}N5GNc~UTz?GRQ`cbw zXjdsabU?M5(8%`NoMR#W1R%bD9Vo;hKFs|*= zTty8B)d`yXOiWqOIu;%R$IYqq!M1@K$|#f(6se5p_rPr3KWSn5Eq2x8>S{06cj4Jxgl|IbE_EUezm>Ag)vW%Z*$a-Gzt(LG& zPg<6L(ucs+6DFN{({}#)A*h>LiECnJUSp%!sdsM0Ba*FK>u47NnY;H&zis2Fg@?JO zr}09>2+yJ4DvPnMs!}~{FDwtduBHGcNQ3&7u5w#l9ep|y0y|Ew)j!~{FM6gX1cJ(a zvGPAZ5QBug&b9n};xi5YgPmdQ$(+CUh2`QH~B)*$_W(nNj3I)!dyI#oN!u^I4Vi5f&H> zO(FwJrzC$g358BOG@LUfuo6uXKdjECCzaGEFRyDj!Vx*xOy`etp+zZ@cqc3*2;Q1| z`M6jj1~$5fR)G6onXI{qefCa2^=pi-UGHP#yL=wlMX0N?-) zbCdmk*mySBVWEt1(!D*Gv%Q?orNMPYtXu^eV@+~`{gh+(CN6=lZW|7XmYTy~y}}>b zOnA_-16p_N3>ZF?@gRi?Y6(+vWF43-7N{eokcdJ*9Cr_Z^bl+|N0V&FCI|FVgzn&c zDz%!6OC-g=T3Ua@(jjX2F%M=4GW@cjE-~k}o5epKXiHJ^m4%p>fy&<^h>l z=oPHbdO|{;2fWyRyh3F}=OBFb`<<#}ZlEB3j-4i<0XqXHB=+AMmmA%K!#!FG|F?}# zEMN-HcRj3L!$(kjKRm#5a006;i}FS}Yfeg5TF06Mpbmd_ zgPMvy@+lCAs`8w?Smx_)Cf0 z^}ow~Q=X<2LF3E(|G9u1;054A2pOR;S8K`%4>*_VcIzqYVx5pMZ@I!fZ;{{S%|_#T z#*5XO{1>r)Y!i(!{eKVe5*NT4v!t&JMc)g+g2$a#^xb|ZB#+ zFHLnqLE8$PqC8y3FB`k+efiXd3Q2i)_^{@HdW?ytAU+HunO0s^3%nBy@JfR z8`j}exwkj)7$ClU4&HeoZ{x~fpgpK4da6ib-k@O*0BN0BtkXSrsL6x;-*ES_k zFq3JY)j4ZCc0Y{%c1#lEn^fI#QP;B4fxAUF2<^z8!U#}+Q0U*(lo#Sp#1($%q|&x; zZKnYWPSv`tObTF}!Jy^$R5Jp5RW9&6yr2pIuWwCz`%zv(~P*Lr+Mo=059wML3hb?(}omG;$D zd*p4_xuU9KG3IkQ1cHs1*QlX=S;Rk#CFQDUrOgAgYkqUKcOfBiv7Q@(vh3(Z8Wh<^ z-?d&x>U%tU0;;I_U0Oso`W^Oe0eK9eCbO}g0j*@8qwQxOk8qLfF8=u}D13qkjT)WP zuTTZRt0-wyi-#Ic8WtEJ`_)R>QLVQTBG!T&8PEQqM$;!uOQ3m&TI%Xe(CV$CE4c?d z=Dd=VCLkZNUKd8I?sghnzPYI%a?vfMfbVZzA%!M>*H1gIFtp1_7D!%ZJI7keg z@Ks&pJ_E2nJAw=eOYYTw#Kwjl2~Mi_o?Su&(U6erx2Bj=E6LHR)|;SI+90dVe-j$` z=(Lw|!BI0G+_`LGW1BJ)G$?j{gyq00h~c37U_UeK_uAGi|vk zeMpWLE!^b$Fftq`#LC)=11^et?3e?CpOSRuGEzskJHQ})j9dYJw{)z?UaIs2Qtz_W zrl-_;yPXeWuW0g8&sl>>=2aXj+gA!&2=I3Gtfi8BZD+Yd?gemiROBg+j9WsQKolu zVn8ek?Y2|;p7gXH;t@v_UK(m!WHI4T)MlYw9ZZeOcc=(upRu<_Z}d6S@k z6KaLQH(epn2q1zu0PvmKK*|D~FTXo?tB|c$51rZ@TK>9XcsY z7A+aR7ii%i9%!zF$pQz2ignuDsY1YjKRLvO4sE{#=#c!ncUDo3Hio}sFd|1gF(4O8 zVlWT_r)%fqQFCTWlA6KpxKS||n42T>Aztv6Sd#*t;c!VN5GdFk$h3E354-e646kxJ zSrz>5(cwtUlcB)07+BH~XT1c({LKAG~k(zR|v`MT|MgOqfYJPaI z_2B`i`G%K%FW#*EgC_UsKzm$u5I}Ip1kw=BA$!{giVzpUFvqNcnTgRVo!c_gG5wGx zCn-8Uo4K_~l_XKXQU)+e;R1Y&!rM>u!tiOZhhlKR{@J`e)+Im)q6ov9LZSf#nbQq^ zUz}VbGOT3H?@MK`%d*IUnz|f%yz0IngOgJffgS$ucF`CMQypg@13_9X3 zYwB49qfsb&1Aa|3w_cCjc|Uc_N0enmMOb?+(`MV7<;DWCP*tkD21 z5mq8t)es zH8T&AA1phJ4K89*a={R+0lZl=WJz^G#G-84;OjP2%Jg4oe@npg%W*G@dSCm$1dk|d z>x=>>4O-S^HQP*wyqWmee~AxQJv}yx@eVg25?OXW%=dnN{W3lMf6X?+3-|0G75AI? zzZ%WFah`-n`e7g?>_7n5{c(4d)hz=AhF$Z2CO^A4bZ7+# z?OWE%)Jo*#iv2s|`FPUn^78y~#IJrMioy58q`4y*w)Gfa5Iq(kI3F9Q7Rgt`$a))> zJCbPqR@xAm13TGC^3JeTOUTBe(ULrQ2?qFfU1xHa_Z0QWIKhvj8DpP@l~<%ti%*^` zb&&=@O2)mu(t;*bV`33r^muaEq=^<9lUH=I$G5HWpM%W8zeumMH_1O$cY%n=RPW(< zCIypUA2^YofGv(G0UM+%8x@J6y>5m^C>QyML!1Vix9s0p@J8c+Jn#XF&<kvb2m@WGyy74lHvrxQTTMdi&+q)d4t;R58d;Q>8d+Jj+O9Bsjq5J`izuBHnGM>HY$${cUU8$U zYE_uAS$kOob&!sVqAYNDNS@dzELQ&FzzfUTWHyr+RVUC01bvNeyF&M1WJ(Av6J06| zwMBqnGMrhS1(Q8#+|*xKviF`a82yLg?<=S#bj#6N8l&i@`$BeKpTO?Ry?R3+2XV#9 ziXGrCpbs{nvUyKr#QN%Vp97H##Yw`%6Nfh+%u3$x}~j00e!k(v2-3aBp8!e$(& zOA43Q<5M=2+GALk2{6BQiOIB{=W3U%8QzdG2PK8RC1z5%i zmu4XGUgvjSZz^lb}KsQDl=64F$i7N@5Y3~Xh0zF3U`QbsU#jFmBbyree^6!l+3J}4K zJ-2gNv;gRWB6HJG)dnlVPL9L64#eu^L->AQYoEg>r`w%qV+3ORvgUO^7be{P6(5kk zNAfZh;u1f3HHqroNh1wk(pr;N?FwAk;DWJI zcs5Y5f%YPYxSh`9SBtYpMzzRDU1jAAL<@#UPvU@DAPR=z*Y`0m9wX|tl?~!z=)H~9 za$hDq!9BPBM(=t#?qvf7@c?Q2Em(OwHZa+5fTXHt=rC@27^46qJcZKNVp*}Bix8J= zK>!&@k23wJXyhh%sT=AAHcpEKVE;gq-ZKkKGLXwQbKHna;(bfA)xYK zD?{`ft2-`;6gV#-K4T?uBA9LrC9G)!F+OBde!wNV}vXH z_2#~!#nP5t@2U0s7Y2@M2q!I9ysnG01F0cJ0$uYuZ^GaD+|yE$S7li>va`=Qm#x|p zwS%gO0^IIHZf4*G4Go{$*x#x4u8$$-)F7=4{okat>YCUm0suWJVEJpC@U$3nELI8d zD{q_*#D7My?zwlBJ1|9$jH&ZxbUgi%U^5i#O``dd8Q;28;eQq_iditl)~FynKoptL z(YKQt;qoK4^UC#`MAGkg-WlJ{nU02z?1TswVo4svECg#MHGjy&8O0NSe;&)KFcC${ zf!q2%Sk7YUiW|hpm|~rBYL{^ll0PP9qjOks) zYc6u9PMnOAW&blY8La5z%#>aW4;oi*j(LoEjdSwwjrkd58={_0A}1Rpc{U{BbXE(d z;UNKrKu_DvpEWifI%%P4k73}qbyRf992 zSXA47OABtz*_f?Ydz6w`*|nf%N+)V))aDaqoz1xL(%3A)6D7gZKrS={0ipql7bq;R zdFaJv%-J$w#v$vK012J7Fy5q>ypDl) zC7BXf7inTQW4{Emb~orDKx$9~1`8^eVIR{={QVMEmAf-4Y_KS?e5l#-sUM|$-YA{v z#H+0USOWsfhpzjzX97tYeELNDQCPx2MRGzd0up+6l{=AMf*Q;I*9F}s3!>n@x$XHYjw3-V+rIh1Jlqo{rU#}6 zvtTMB^Jw(Li85)iqR9ueAwZQDTaGh7$nhk`I{wAq5}98-tP`XQ09!OXkWep(IQ|C! z$1T%`bEt2O@f{w`S=dfMySd()FB^<#RSj{5+8{FaUn6Wn3CjUx4+Ql$3|u>sPhOBbbALob2Y03{S9^cJP}AT2( z5Fpebgd&8NP(w&^{oQ+C+&|#HxN|4ZWS-fbJkMtLvzhrm`_0To5OU$K|MNJrIZd(P z#r^%)Glm_FBjBaRnVx@u*@*;K1Giom?{6!03Q%{&2X;Lo&r7^*v~!NZJNEi~T~msF zFGZj`YJ1Dg8ROc{wL6V5Mg=7ipJX@!5~5Hs<-NNvqdQJp>s!CdcREea@i8R9 zj_{f}d)tMnsk!PJcx`XEgb%Sw;^@H^+XmT*dqu~GyQ^bS43oMTPY5~L5(FHchVjgJ z0C#geyfO-shI6`?or{9Af>)gt580cKLc3?o{l1vD3KpJXQG4|- z+4bZ|;9(*baKZlVeVOd#3BkCsgA>(_`*NEe^Z411DQ)w2WKxHVJ_@@@JUDQZ=R1s- zvzvBV(*e_biR<^Xkky#uKID@j$Z+PoZ)5$n>&=lJ@|4`?QR+6!{zwV^I=_=uyZdh{|tW&b#*x7qrQ{7XsUriAa%HEuNKHjwXsMDcUauMP5 z3I!~W?sVv+n?4W2JKhuoGjNmEf=*Ekcm|@K0l4o86WJ21S__!bO9!yxIm>9iQa4Ce zN)h=otoUTOG`>H5z_(Jrks<9@Zru>mG)ojjL{6an<%hP-vWArAEFUM%8rs=P`h;^< zc0={eAQ*@t&1^K0YUVL+q7L5Ip|L!0U}Vm2I;N9I2dI;mO`*{=z}!?L9iY7PD{!(Es#)Z=6&^{1y|cC!fFz4%$0@S(dR-gn@btwRaNwzs0DUhy-L6Uk_@{IhJ4g-W#Am68#jfFUR9fDb8>kawn?U zyGBeT>1AvdR$|hf7^mN65|hMDUbIu-gs&2k89;%w^J`?OaGtf9B^?u%bXZ@1&Pwmg zmLpgAU|D-!sAu-eMMzbc^mP+|Q*VB6XG?taXQaLDX{Jo;$qBCR3C4tNryJV5ey!%x38egDwGSE! z3Vj_4tqjApZp8`K`Fd;uWZgBb3DZpq*L*O?hy2>sP=pJIW<&**`G!^8O9Mh!MKPQE0ufDkA|tjeY+uW`(YQo%{g zaDQtiC-4?h?j!h~2XQO`%#`rT3-|c?Wp71>g!xQ+*7l8)&|9@PEQyL6h+hN_9hQ$v!?`2&fi%j0US+^0hQ_)gCX3*(6n}tb z^#T;k2gn}9l1^Y0yFZOSpUSH~;>Ce4<0io%`)WK(m7yVqghJLV2!d#^6b4144#ee_ zMnHWfvGjrcq8mbGeCO^v;{Q}aPYH`6AIf^1_at8u>8McJ4w$!-0Wiy&XLyu#>8sqG zLFAuVYCxv}ZyjsJ9ZfQT>KEtN5s`ch1~QQy&PZBk{N2(_SFsU1p)y1-Lhp;{r`}<{ zm;y`zrT|lbDZmt93NQtj0!#s>08@Y|z!YE#Fa?+bOaZ008`-quL6v2{QQ0&P~d{Vh%Kz}msXEJ zqn8;R?fUfDi+hDC&~8mDa6gk>(;5_t*V+W8M9mRmazLrk zPF0oq9pRFt`HxWan_$Bm(=roQrdn3>cdVEPQ-CSJ6krN41(*U%0j2;`fGNNfUprn$vBW zLk5Y`8OQW_!u}C~dW2;V1iR0JLqTiX^VFjNd~1jX2v4HrA_C~ut&~F*+A7As!4GG= z*Kpw9x;Y7_w?ijR!{F2-)K5$|WN5oR8=jHt-?`O{48cmDEbPqexg-3PY0VUx^l4K- zN{$|KZ=a+?4Q|@r=+E^Fi}`AYIOty6nwAHdx2En|&F_RcVh@nUw6guR!(!BLmA%fG z>3W9WPKN!Ul*#@#yAS^*Uit)5SUzv0AHJ2FXd%~ z*V|Q39*7Vfr>M&(alRKyI$)_#WAr4Df4% z1_yME)CbP1J$= z24loVlosB<)L;pZayaeAHdnDX&yAVwh1l7Uuh(Nn^c|sNN;nT?tsqL(W<<;hCY=PH zmo~Lt!^v;6BS7<-@d-lk{E57qPYhM2iJ#_5&iXJNdx-3jBtVcYRl9_J+adh8S z%T7*TKO7V6e_hKK*L_cge~`W;i~qX;G;qvKP7lHI z+s(a==G$>>A2wuZkj&N0LeVZnx=|Nusg#{g!0$sah)6!&+1|28_%Y&JBxf@(UT?H< z9uO^NbnHJz(KCZu>uIopkXg#8H=?6&HoW@~ytld~G0QNfGTu7)&o?!7Vlr(88L&nV zKU90E%dZ6#Z2=iZojL@+$B@2mF&sM`rs-I@A?VOXJF;2-TP}iOpNU}1hHWv}16u?3 zz-2Nv&5Z5S=TzF4HO8NJkcgc*1Wj-$5PQflajxy8&uZ;VnzpTYhaGOB58AnR`}Pt z!~e8bW!iMm!THx;34UduqCg}68=jv%T_d`+jn;pL0Rz#&)aE_#`PM83YBm#xqJy<| z{sH}&6cA|bm`ntRbuoMy=Ua^M$uN_N^y}^vB+pnyGl;vzKOR8{CGbWQ)!>1*Bv7a$ zVULcnOaY~Z<)hu?1(#H9McQdcfbNflyQy%O6WRqz(zlhQ_mn7u!_K!a0{;m*HAzL6 zjnAUU`9dqrhdWPB$Rx>M`-;w5FL3DrC9`Z8F$Qhy_G}`{-F)Ra2kpBN>ronH^On;Z zc>;Poauv99!!z;{`5yy_JGr0iv_`(LarC-aubvUJUX>ELgESnN9zp-ZKe92|fIi6e z*>s|}%fL_QDX`?u=7uAX}~`bv_mja)##|Uoq?e&bUXOZ z9ZMQN60u0tRf+*)PrR}UHdkkNl^mz`;@1tZQq;Pm0OcxZ z=xFTC*-T>dY%po|rKu@3LJA+M8C=hX@aL=Cp$n8UcG*~3_{G@D4No!;zn?7YA(7IWJ= z??DWHdoudOx=QwMN10jMoL7D_UCW{%Cp^^`0mF(h79I9!^n;&J?g8u;u z5!jxnw0-AxeLLLIX)!|uBC9`B3eO%1TXS*Z=K3x^hm9Qa%Hg2nrP}s(RS6FQWR?hk zHeitndgCCz7u;O6pv<-Hm=)_cOVS88J&8CyS%|X==kQo*c&P{5;p9T9=3Zv-2)aCV zSlgR8DP%GIr5Rln)J~s|yk0hmY-sOUI`F3+EBengXya)`tJu0g&1S;3eT{T? zDwGJ_Jy_Am>kqJ&B!)z&6AffpF!BYwJIJqf*Fg+djh0M!DEmJmeL)RnWaCIJlPfa#1Jc|1cEfn{1M4OGD@!O=!HX#Y z4O`en^zJnDMX@%+^3|zS4skxTLnEbX4!ip+(@X!*18Hc#yPOawd~KVoGgICrqB*zZ z+M6U{95XX!z%iNRKOLKXcP`lWIf;ttzI6$6h@@+t(rjC3Ax|r3OF@~QbNhsZo4BUB zVw02liWOu5TMhYEj&$E?O^!=CM1s=tCpIa86rzyRJu0wwqkg!8cPltp?13w`Kj8I( zpLCbjMKH0Cea%HobF+QSNZ{pDx(m{|X9o?w!JbXNr#}BG-Y15ebIlgN+U%xvxymJ` z9<>ES0EHahacF~cH(NGJ`m^vU*CvyXAM(X{6oHDX|1;%snH21-zAW7RB>((pAkhft z+>arZcGvW~gGnZp)HYGsnIw9G`1dLe{P*&#gO&CIxnLl$}>erU5S-5Wlq?#BcewrS{6e zlA>BqyRXDiY3)&yBZNy<@vSEv-IUo+7^rH*05RsdvL*~D{1jj>MOdmib13OI9I@ii z=<@5m#^lTSMZu+Wa>UhOQ74;5)sm$1YA4o|4fKoGw>|T zH{UA>0&~PwfzJ0^X>1|7lVw46ddV#s`?O6zx*t|tO( zb>y_~+6-b#p)*FgaV^d?ig+w=-9|LndlTQy=E zV+71}Mo{*zNc*`T(0hAxO|<%Uwo`~*vP-Z~BB_*0dR^KSHYJyC<)0OtHc_;lu~eyW z)AuOuw56hV-5{vhA9myddYZpqh5if4J9(;k7=O`c{#O@WVu+nQsohE^RjB}jqq0IB zR?vx6SiDimTuS6#+5C2OK)l*xJ9(fU7dZ0XlxYfaOV-#>qpFQDY^ul8N!HXHNhZ$i zjgc2}z54Ip8hJ-n&=_nd{&a5s4Mb&$j(Cll9-@#Pv|iQSQn!hT(tLb_^H>! zd5Ubv2j0hcV8Kd62w?Ma0fHFr)B=aTYljPl`X0#PbaMPZOX51Bw|6-fC$Xh!CWO62 zrQtx+6IC(XkciCmd>!T8T4;b!hH<3B9{H6@?NtxLzNo`c`1>nx&#bp)B)MpBJ6=rs zqnAoXZ=)62D^(Mv#1IRMr-(=?Jm{8q!bF! zm%qpgJ{Tn1<=7xy=97I4@-CUWKUl{O1R9RqpBYIv^LC&}heFn(RiFGYtP{-aR+Sp5 zGSYs}FNsa(9liI||rp>R-Lh9WNDR4aQ^Z{UugBLDmA#3jVo_J#6>M zO@BMqes0ASjj52jJ_NkWW-+8WFfLU(&nw=S{WM$tvU7UM>fsuu8|#diZ9M3I?V|aH zl}LZ7{zW=hU34bB-}=ZsB*!W&wOjdV-`A7JL?M#u8b3ZgU%OobBfBGk9k5Yuk%#27 z-ZtTxiMu%Dn|FWmqT{^QDlK^WZRt(>?4hBtAdO8I@@;VzSM~F}hd&6Onu)j&<;)Sj zp4SbhinZ!am#+^frj2*MmaZjsU&=|I#X<#fqo8sXetp|k$vd;w>FV}N7L+d z*4(~o-xX}`d((&rfw75|Ud=(5y-0PR!&ONywx?{vOPqFPLfzJRrE(#v@E72`sfjaf z)2bIzSSo$*bT_39Y2hnCj|I6FTQa2pkAOBuIs|!sy&}y()-%(tf*%nXw6EYS-th=) z^-Q%*NS{K9TOE8PB(DJ6Fb{i^{vp&(V{EW<`wCgWFK@iJ;Y-9zw7q}l_VmlnTgE>J zpgF_maIDecoO>3IHs9*1#Lw5R{Fd3Fbh@4bq6C4-TUcAe@}S%2S<$NQczFX^<> zk~8VUUv|D*tyjLxq|7+(?_z)dhIZ@a^Q{Piw7r+(J>bd!(Tkryo@!lIP4cRM2yI&R zt!dQugfPt6?fSC41x^O^q1auo#oGPu`^NSo?xh^AngdeUFPWFWd8vNDNW@T7buS}x zgWZernlDDpD_$M6SXF$L;US`Z-K#JwS);Ev2R9GO)2_Zu;{CbA)jRJJk<%}AD<4k* zG0KCU>dS1Q2dvek+Ztbv<)}Nk;17~VqE9H1nMa6jDPvv4t|zS5CxN{rDc3r@3*l&g zZXG@EOKdGXJ^XlFCa>1o5-1`mc+ev=48J%&q?lq4luHitmVZ1l@Vc|Gifec+i6o5 zhVe-zdx*p*MYZ>~bEI59>QLeCEfa?Q^#P)pq95U};rIlIzD)hDo-r}BqzQnAjHPi! zO(PFP;o1S3*m&24%8yR|o!HBq^f|ax7;r}{L=G4^|XI|J#kgwWnr`beq z?5bD6Da%2TE4?Kk?c34`>SoE^-ZL!QV*n=}NGT>z(=tD=OCaW4plx_Jn-q+#20pO- z>F&Zpi*lmOnU$*6r+%T1pfD#s5YZrW5~mnEew*adlsm{ZObu*tD1d{mDCB)B$6Xt7 zVqHN_?}M90DNzkwGg{d{-sSZZB;GF+0v>y#~= ze!Xv9)7i#3*eFbF%YGx1U6j3xhZj&|zw+g?sZaFHvt)tiQ!V6>SeeHoPqOiAa_)Jy zYYN}GiQEf`4JYatSbM$N^mZr|Ye$d_2xvD93k*mXWFH~F74%T|;sI06j%lO%REHmx zUjKzwo0?dD2?AZ!OkQ`Zy{b}4R>aM3P+GQ(oQwqMmbji65W-7)qf@=nc*G+!8myK9 zU*q1e&J>NJe2meUUeAx~Pb(+~;qT55_qG8>WWG;&>1)|&Z0RC)!TXq)` z;E?CV0I(&J=xoRy<$M+Hg-den@8q;lwkfOR>FLJxNeMAVngAtSr24WMrI)x~+Qe&O z!fxu$Gl#KFnBGl(4a$(@XHVfZwj1dnY>xaU&m4grvAOraJtK@Z;u@H5b%_T1-%1X^ zI8q0n9_2POsEAtn>CTGC9`3_S_}|2+L54LiWhhXLyaMJ}wZ&7Z90%F5Yp z&-B86A8rs@frQb17@);WJI8v%_QW}Bc^TCccXPLTT8bc;%ieuQobQZM6;>psofV4> z$?JtF=K5(~nSS?hka6-GB7=%K4(XU-Tv^S9%rYakNSp9&`i6cPt z@$}o(fUc0>Ey{TmkG2qAcTZ(qpaaIpbC$ofR|&q{uLwV`JiZ7=PM+*6URnTmZkS5b zEMm%c`T@gmeBXlB@d*?z5JNd$= z{A>Fd+4alN?w0*7WB;!E&or|I1(!8rpq3zsRe3zjR`t+d07UY-ZhA9Lh7Ce*bPgsJ zxul{JWRBCRX4|@XfOuQ#Ug#&MQ76_TI90my0sr$>ln=d^|d3!wJyI&{m=WDC2r&?L`61=NH7S#C+Yrc3%>V zK8e0wN*%IUoLsWM*KOnYu0N6omjCj$7pazjv})sm#M~@p40U5kaFSdvRSg1>65#5e z)tpAQ0_YeND|-#g`TIlti@VRF@%o-OQ)Kh|h4#!)VS@hnh^V$xG(+p`w! z;Io7T#rMlgx7J6-TuIhd9_hLbQ!$;T>@2+)G;~w021NNxNNN_5F6+nqyS3Ns+-TbE z9n7;Jhm6YU6qfF6%_Wik6dyYIU?VuBG-3BEIMUP2ylDK8G@Yt8X(*2QY>&kl}s=8WU zV_L9y(G4%n{6oj%ACMT{$zkQ{!m3>zVxxF*$`CPRC1q{VyM4Ivq$gMZt(oS(P6*-- z*8H&`>v^9QAMzOA&T?7RJ}nMX2Z4-u=CA}4A)y_{WrE#bJWmkY%ld5_vh8tj+QxT6 zKxgDQh)VKU&}>n37~DAI**R&UEU#p554MOGd#nsS>}40YyD@2VzR>tIb;w_vJ$GJm z{)^rM=+L&U;5e4V(=`*cZns9_1M`V;lD2+eLkPB1&1!@r!YJ%ixXQm{o`T;p*^X{S z3IbwIC%PG@Lxl6rrm)!XoLwYD2Wdp~Y<~#!>K*dKZYoDu&1oCTaFuvy0kpQ1H@_5Y zcRf9%)6n;}Zo7z*pFD9pm(!rWiV-9Y}!62t=Rs+Q0yyec~#K>mV6S>BX@#Fr%b+MAvAK z?+LrBYSTA~E+5i0xDPXlF|#Fr{8Exw z;_nC@kenc+1r5F&HRwjSI3e$s$^Jf-rriZO<>`zA0yYGliksx=!kX=;qsCL{{8B)P zQq$a6x|U(Pp&$1Hq$sInUq9z-uZvXezp!Z1%0fyIwjapnD?QU7dwCg9gD~ck?Jh=Q?YN4S*ER{5v&i_(a$?%)~L@^Fv zR77$IJ?J9@2gYw<(zh7C90+>ZN<4rO+7L;#d4q4HEwqK~kpCo6aU%@1A1kn~`~6W{ zC%$|51!cxo2iTzBVejSU{)irp++o{r^r=oJ{2E)FN$B489lE`fKAswH+nzk6!*3V9-%_R+3rG(-_#=eIKt@M& z(;0U7^W?rQ#>NP^BMeJt{Fh1Yz6aZ;q0rzDN}8u3&Q2sMjEzEvA9L3IFKHaH@V{%` z((C0i0mwfiLbaZtU8`C&edzrxF8;KwwX_<4q)a{*&P>+od3MS5%O z@-N5E_Qhj{UFqL|B`Rur;pk7>fh6+(y3+e6R%3`U-G1$VHjDpb%GlgrN!^1i|38Yg zM_lOGyM64)V(e-RHg7?3O=XB;9E97?T^(4gSx{L!8lpr8#VpL(JH>n(VMG!UuRB(0 z&SB1UI)fUv9mQC?FTHi`|N6rT=9wwL6krN41(*U%0j2;`fGNNfUNrSi!G@UYque(v3~Dj82O;|OZHVDs32IC@wCHKNM( z|4JX3jW7k60!#s>08@Y|z!YE#Fa?+bOaZ0u?Lp zEL7S%wl&updX;uo*0y^aAO;33LvZ9u;S+(ys(>B*C^%}Lh`mjZN{OK@G2&qRo1+Mi zDuE8_{yGjGwNud1MU33v#v$~o3bzgAuR^Gm@EXI38yroQ74S*}oFqNOEqlxhu)oL9 zL&dQRs@7Y;KjlL*$haR@i{g_dcx<8B=FrM&Bb=|3y`rX-6|C~R9 z^DA_ECnej?$=))%__Ml_u;UH7U4CVS#DI}>Wp0iWC=#iQ%9ZA^cCrFAl(*Nn-Ez#X ztu&lS_oz%=VC52rR~q7sOwvocH56~8r<)e!)!yB(%&DlXftN#MoO3EF^l{c6l>-lQ zF;3O8N>BwQ9k=y1%LpC6;ECn4&@l@OEJi^o9|Gx0DZ(g57gZWLh8w4r<2;6j=e^T9 zgKfnM5M8fBF6Zy1)gSRJg zGi=hW$1_VH%{6}INhb-FwHAngOzQf+QH1R%=O~AUFxV(Pec}e!M228i!4n(HPqpI7 z<_?yQ&j)Sum57+&zaZ4Q?v)`lUQ1JnuGR~4hYGtx~gn664uDYXD+9d`H+5k7n zIbp45%jK`aQBt9JVqIA&d6Iv82$6>#nr2Rh_#N#m$ht=PMTdlxiVUoyr^mAMD$0Kh zzQ-fc2i^#@bDbxou+VJ%?g7UamP=vzwSHvisD*{nVxTd&6)n-HXemQKTLk^L7p-p< z3yW8beHZKe!Cx&BSw4odnXoQ1#E52=VRG=E$4vv4omy$SVK78XjNOT^Qtg?&xyYrff;_f|q#C_?2_W!ZxGR4UuVU zOK2?{+$3k9IIj4#Q1ViRbj@9OEoR(x=Zn~I8oFuy7+@?juhdzzUXgI3YCKUfmlT%= zNgc25{%xL7;NZl8uOn^mAyO~VOw=2(_QIl+$6##U)6UmjtI-rXvN!*^R>I}A@0S3YpQ!TQn6^U8eq z{>jI*pXsqX<9Z8&c<{C^ly6uiAz?p_+(v$qGDfjB%de=Bg53ygwitJ|Dk)Md^&XJm zNiZNjEPHB&qnu|^(RWF$--T{cIqt}br)6MU9$m{sjuu~f6iq|Hjr4oHe4QSOa;=D4 z(9^#-_4+l~21yTCmKE{H7q$C)o3&|rb+wYby0SWSGd2}n!qK}I&&0Fx%6b0EN^Nmk zj*IW@@a+106`6EXT{XrJ$bx2Pbv0M_4_(aPo3>I>s{HGV9-2L5ozo((Qj8lUE?-jd zMr6YGn~{!N-d1!VN0_IT{QHbjZ>&pN79W@Aag>#(%=uCudHpv*FI+UA3O8wN57tXn z`lR(!B-y$H<~A(Ms22(5h84*>(lNO&&jY(Z5Wg?y7`b(xN!&1R=HcXWTTl)w(pNTS zyB*p{G_fK(AvpA7a%EU$ zyLj#XD4e558Zf0o*Q-&R&E>G3`pq+XuK?-P9NH7@x;|d67RRI6Ds8VtC=gi=KUB6b z+cJsF`hDc1kiNe8@K0F3;|Rwe(EY(+uju{wm!d%340mzS zbeomiKa0t_C1%%a`5h~zykY-GkTxZZ#3oC<1gGw zcQucgPbAL-XR2PPmVy;X^T>%uVvMZRBlSH^*2DjTIOpAXxvfiB6vx>rpVKwVcxR7J zdOHo{I+v+q(LGe=)294EIb#4vEGyVOsc489W7M8hpjuiOL-aq}2fZIJtd!`y zeQ>+nF!qNANP$YouXi!!gD!&!9*-x~07{runRWTBqoB0=bA7t$m**;Wb9FRyY8n;) zP5dIKn}qWD&JJ$2+*0%Qd@srgtt?llG_(n!OU9_p%>Cd1ze+NV^N8up;~B`ucj#QpVEsa({qc=_JB{);+`%R7ERM7xmTV(!VZYNdAe^P^aHc1^POWUGPCl+nLl<#RV%e=iCa>o za+!n*Pe&0edz`O>f1Zb~N{2BamxF61s(R^7uGsL%6E3dXilM=y61-pq{TF;e9K%gP z-=maU7n{4%mv}Lz-%>xA$txs8q3={Z_*GCLp1kzU(%4of%{l4nOGou=H;+o_H@Mt4 zNTtX9>@==Z$-C=UBxAqS%d%jtnhunvz0AZuixC>UPG0xERc+GG_cZdmphS4bCa43N0{w0@tHIz;YGz8jyE$pr3}bL*#^{~SnTAK0pDJ+LYtdv3gxC%m~K4q zJmW@sSLPMY-^Pr12@_MOZQVA;BxOESLI+2t9KTOzp1LBsV#7y^DsoQ#^` zN8~jB)F1t+_dw(oy(f#}FY{T|TYOi6oLdnY`odn3WD^PQd?ub*>EMA4tgQ4IC@b3- z1K7)^8%_*A>`zxrijUW&@=Yj>PI1@7m3ovK5XE_73Z7N|Mv3HjUoKfnuk5WBUgKot z2?`vQN_bKX*e7^OxzGLn;%K0N{(0pj@uwcHM1m#b-6io5#m`)mrE|~HBvsS?1bc5x z(4vFC^y*$ruPU9EfDp&O->t{Y`Wj&mGsoat$6M2F@q_JJqwJiD4|L7DRu&cowG~psHE%O|Ih3rfzRArY zd-{n#G8`TAVo6+OPVV0Ng2$O^l)E9D+G`kwh&ZPLyHC{yJZr)kuy0OQyXWTqy-`0E60`rhR>uQIW=9humx_HhU zly|$f!xI5xh-l~hl@&dUzB!QMNfb-Kq!QA)pyT^*TFh?|!pqL}VGqp!RvYxfZ&L}3 zU=!o|t-Zc#&t^l;9X6wil;%5yEFNqBL68Tqx*DsNL;BkZf1rL+g0P9F8@E^Cs83+K zt>wpEv{J?0bf9;}sg$eeXRGNxXd^yjyXdo;ip;x@c*f^x4le)a%JZbbEnUX$RonMAZ__QMyMB9G{^Qd1)KikrIX3=`q{+gb z5+CnMc{71+3;AHg*E8{3I3?R6i54g0lUGl8LUdvwS1AwA_5!Wo;t3i9oXt{2tY39iALjm~hyXHD69I4tnA48b(eaJiI*W^6Gd_FGQ?YHtfScZ%+rFX_|*7 zB&cbrSwMU2t=4Z+>|iW0mk_nNTN6@teWWqBwv}r&DTrT%(*~LulG1kU-$Sg-(~F+C zMygL|Y~|Ru+^rmX_Z8r3_x*m+Z_c10?@#l1(27?^UVZR;{KNJ1ehq(g_UF?fJ^N5d z-r|qu+Va0crFgjW>0W`on|Bee<{5m=Ue$H;MgL@9yHqQU8_R`L-3w8A=ViRd*6V-% zSF|hccvWgd=To5gJFf#u!-diBt!+6^3^zC(e~a^E0l0r2AL=*9+dnpjJb)i7KKwCo za`#K0PQXHVT+!~bjj~|XSVfNSk0&-)(k4xY#%&($%$9M(G|EHzk)Pe4ui?ts!M!q_=6w)5d z7=rW>uCKJ_?hsX4=9KSE^r(HR+QHJ{t|Mv z%&R`WW9K=}5wbGDk)+2Li1z+s@7tC&+hu+4up?Ck?KZ>Ssi#SMU)DQn?mr%ZQ*JJw z`x^I?U028H=ZX&Msh~UGmjtWg+=7FFBTb>5%EFE}vD^rR%C4sYEs(V?VOimjg= zy470YYnNI-RDhKn)~Scwsa9QB$XH{`SDxN{+IXI>FRIt4X!^ABxo)M9n%1cBz7z*U z?6*y!r3c>^b3^Y2@p~(t}%EWs0!BW4*ahLxWF{Eaqmi|HX!t52a=F z2faG=^#E!}16$qoh;ySbG4uCvSu9 zgOL$*^BzmOZ?^b(=8nvg!A%*t6_Ko!bhCTrw)11Jt2PtMqVO%9ZIa?>OY@^5 zXa7Kl=H0(M{mW|Cd(^mudf{k)KI`=U8hN}uW?a!Z+|XoPNh>tnF#+OZu&t{yay|v{ z654t@ekeffQOI;h)A2JWowSTN*SA5RxMZaDSZoGTvvv22RBsop6kTat~*v?72ca*LByT9o5{OY^3XE%}k`(soyrRToo`|CU@Wr(yPNL~PD1YYlE%fVy# zqK>yFR_Ddbyz$ZN=aTV0i2I~BbH6W=1Vz_46?5`e6L(bD3VC@_W|gHqd;G+_7AXm7 zl500=HCB^HR;UZ^@eIz^?@O)%p9Z&B68;+=02!S;RO7KZ>Qfqa#|4;6d6Sbo+9OrWoJwz%ubIUoDT8-(~@s}^>2CF@Ry zoO(_ds-o(tFBVj{2gwpPW{D0wIr@GCRe`2H&q?(rd8S=@tI!u2mLmEw=D`!B-# zN*u4eJ)M1#rh|05)Nm`eHr%*)`qT31yr{lE2>THuT%?=Ct<+YB@Ka+aocX!}%lKjuGKtDoA5aQ^GQgl za9M5xvHNTQcT;Vl;6TmXhr?z6+_O?ixDUJ@*oVAl%d)`7u@o%-pGVNBkO8R>&g~sb zH}9OCsS@I)laACyjrg|f&aIz)B>2X>8(iEY-9bj)BtsGXev05h^OxH*6|TOJn@^7| z@8tm%mYOQ&@D|@I8oSO=jit5PUBkaiHt45&YqF<1b|hqO6*4lbp9!mEZw(b4Y~DOO zk|aeZHU4ZJ?`f)BpY8kLCr=z)$kA;@#*T|3>Ke; zyC(^?GK8_*A|=p|a%n#17Xuqes*%HRUn`E`)57(Lc9rZ8ER}^WpBlF&TPWtv6D?jJ z1)l^_<e%N{+|Pe^&z^eva!C1c?%`vpTD~=+V z=hyOexq**rt+lF+(`|7XDI+PAl-j0a(aZJ3?xgi3!P`HC5wa3}to&Eqzv!nMuHAm+ zJNv_^z=4l0<8^a%^DYj%%=5^9!@fm(^fbG2GfJ{lOLr%0Xz+BiY+Xx98*1dDkL|4mM=KVBWJ*Q*2y3n5?d!_}5wbb1<#wY%ABz8DY@%6_uO2}?~cZ4+5E z0kuhF_XvM62_$Ro^Ba#ug-G$_-yL3!4)JU2l*E=OT5zfqlM{X#PEIVZdMG^Lkb)0L z3FV|ah{Gc4L>HI&t0iEt?TC!YYDU*>4rVbw9UI*g|;}`N*kV8e!Q5tyQNdG zpJnOn^vSPTVTtmn{9DDH;jFY_Ko9<7{;Eh79lharW3iX;a9diW%m9D_8 zvr;xK)Xa5ovdD!bHDEJOLkig&#D<&uExjD0J&~+Q0r--(P7%9(yZz{*Gbz&(H77I0 znyJ@?S&a`5asyPBSGlK;qzp}EWQ;vh4kqHh%21X+8TsQxX1RJ+M#tP=?(GFv6oL#0 zDS=||Uk9pWGnQZVZhh;A{Y>?5FBw?oeo!f{wlT%6?*XN}H3hDT7%k3PJUp*`o2Q`u ztqo|n!l!Y?LU!(kigt5a^m3)*2M)3Xnv^G`k`e#hvw2!@!Roh9k#iE__0o44bzwX8 zCQZAPijmstNnONzc)fJH?7l#Hc4a9s3;4aUt}Ek129+w>J9FB8zvW0@2*(?U_5?w~ z5%B+1_N+R6zE3*F^o(e2rOn$xL~l_xQ%tQNwYIjDp&CSu$b|4i8y3VK^tX^}s7_^D zGf>mBlb+4E^IB{eopjaAr&51~I9e!YYTG8AEuJPClzpebNdBvwts^9Ec>t;D9JDkl z7G~2#`b$H>F=K>U3Z);Ls0$a_HM>uUU|NT+Db|Q96y0)E78c;e1hT{XXMLu-MW$7L zhzbh=9#uV}C}p?`6$cUg?`fmWhzZX}28u~Nq7y+9SsbI2p;q1opg2)G1Z?z_5M5|A zkdJ>KgD9^p?QH(_pBJC2j@y-!PhQi133Et%i1V^*Ce}Mypy=hr>7TI1SQI)I#t$PyJ4i-1^O(aZq0GtM*n3_rT1JlrocU+ zGaXd4YviCT7^uQC(%hhtjaA?{Ko5XGOLaaePsm!xqu(}9w8*rli*gm45ot45L~!NfsqV>tIvm*uL zt4GR1_*@dF_Fm4ZISTBOviKBFtg{U{@ z!7?AVbt?e6BV8X4C^F!OCHa}_6poE(`@yKz+?4Kr)vVH!M%U6w6=iWroY z8kPwQMKT9a|YGs3MRRIsGB?P5&&9NAaT5#?nD`OI5iT zj8jyWCw{4GT-!+lRg*e=z-jr6}- z^HoeQ(xDRTM17r|_=X3meBghS@1PWo0z*N%_BM z&$*8p{P_Tx9OuU=8Md5isd?~0G*3XZAK$yRpdz%m<>8Cldv1>SO#&MWLW~Tw4}Ft? z!tPqH&xu%Q>Km_h)85R_^nI!TLaIfSg!_3B~Caj9f^gMhT4F5Z8akQyWN4e;3`Gs))|Dfr+!^0#fFMBX;P!0qS8cq4Or+!dQE~#Q4vs4Iz&J~K#0`PLO=whh8`f0&;tYr zEeWaT64CR=U#+?UPBEJF|$ z+%BLNU4HSzC{M%3$-RR~ds;5;)iwj$$KS900k`_t&od@I2A+94qAK}e?#|WX{&;n> z&)F+P-GQMuMA;13Mb}D^^Ri1zWSI|3l{}t(#B&puie`(1RvP}?b8W1Avv5XOwSJm< zPW5Jp^aSL~AE+FshBaot@$d21l_SUu-z=l6pC{geEKK>jwYNUs_(y3cgtu0}y+R$& zt#%ec;tQkC>jhD(G%GcOvgc|gghMuV^uCys@a+t*3_e<4v%jpy_EtS}g0Ore7cfffSS+{r#I843Bwq@-P*$jlYvPd@`DqyQSyip}%vUR& zLHaapP4#(`uj$DyBH?O8z(l~R-_LB&>B+RPiD`5-hDWDqL;W9UQ@#*k5VS?686 z0=OVEC(MHt`TaVjc-j4ZU{j9yH@mBz^g6E{pSms$o4b8oW0_Nh&wg5(otRsj;4xGB=k;FFlb)3!dc>3Enk-wtbYC>Nh*ibud4w<5`BkXf{4Oi$F?yK^ z-EfUODhnEXtP^+{d-81k=Z*mXiL$uM4~+{?BrJ-;m3a`oIfslE`;$5|$7NyB##-^e z42T!E{`knb_s~bnr>^&3tLCB9IK^Da$US?t_PdSCaP}|CkDiRI>pjqIORAfve@ey0 z)f35AYRqlsO};oe`QK+PgPV?Jf*0hkt)EQ^=aDFvzqa^hs1IbH!+T39Kk?Tl_k^QT zhHX*uRG;N8>yW8Ub)lKa#x-8!LHAF~{Ql0Ssyo|?f#<%=_2tcV`1db9k$dW4`8S#5 zp)2#Ko%x8)6ipW&=8-Unw+ha?Bw%`~gX`gNoJ5s=vPjYnucWfqpZG&xt^raWOgzg_L0_K&Z2x88TIEgUmym4nH}I$Rd}z?CuO&RDDT zNOmqYNLq7wW-&ixlP3Gk>LoJKz^vBIu#dK^pZfI-pO|X+y$#%;S6!W(zx%P*n(dyp zgK@=qGAd|1v!WCA=$7*-h0IO}%(B zt|(M8YE1Y3(T-RX>g>ELy#T6&47~dskszWG`Y$cAP%X^xD!;Gm*h}G$x@W}n>5qg3 zpNeOzzoWIzxlZTFl7{xU+LFIW*q+{Y33RYAP1=}_2wES!5(W&`cb}r*^>}mwJq#NH zJuC_@Di!4ZG)TQI?sre^Vwm~$GsNY~@6KhwaX}x*vM(NgJ#r~;So-aJnsk4{;6$q` zPBnIH?1AieFz5M_o=5G8gzI4!3vOo|w^AGVYk_bgT}PCf=s4wFZXW*W z-ZAmy3wmoZ?@P(`+&3NYON!Mc${fGp==(B$kKmbNFWg)WbgjFRp2=`YxzY+EZEQ}ex7PxVIn z?s>9D&E{DN{5u^rm*m)c2Ld;KzG$jR2cI#{5iafOKe8Wc$tAmMiAbz^m)E9@Vi)*7 zM8|&ZnOloW$+CM$6-ag}xdF&4Mn^|yy(X zy3y`u8xe+Puuj068=6jt?@ipH!k=OfZTaXlojBWh??0Z+R=eA%y zB+!4EZ`Z#GU7?^;u&|VUx-bK~o9I9$8Rrk6&zvq|!Q9?CT$Ejx{tKXN@qpcb1t(h} z+aarZ zgH~9sJ!)OR4M2d$5RLL!hiR;vQP4DTAyg}=gf zG2ElZ?||cPuZ(wdyqVpV<)cv)Lg!ElCd~9;9&-}%z=g>bu z#q<$jkZJ(F=vm4^>8%k;+qJ(#XUUK%n1F+BE60SDox^wo(9ma<03Zwt6HW(cE2C{3 z3}#!X4~Teaw=18077POZ(*wuMB$o77E2D=-KaH$L3wK=aULC#M^Jd@K&7!+RW?=&s ztmQqlD(Ksl=k=J02O6MGQ+X6rw2I4j_{f7usrn7*8^g3XE z9YD{r$QKt0rTR%%;Q&hcKL*d!50l$wxx)7gD*vwlkY$iT%5)l#;;sE+yu%fuToP+rT0QxT(PjAtT-B^4a^I8O&jI=D~rnDnj1;|J9%Y zK-Cs(W#2^u+e|dDu>=2a)ADEl`ycaP#kvks|F3m6{5}(qfC$S11*m+I z4s02g^M>0e)Z4M|6F-+Nk)!6i`CtpfK%!qVxLr}9JqO>GIM!G7I1^wIJGI;}_3b8a zQPmYyVEz(^m^OM8#Q}BtFuFu(@ckd<%_NKY@(3W!rXcfXz{;wy){_X_iBUpyy!LP| zqbzQ0iZLUPaDX*(b&4@4-0WJN844k%iY*lZ3iko}up6qJ5vB=#nYv!?JzUHFB-3G! zciyu>5q-4W=-k9$t>(3g9cpP9DK{RCeqmf%JHJ$WLme?+Af3}VacjL43yRFwLyO&J zvx%zE#ouIdD5X4skQwU5ObkFwl42d?&Ih~1v3*K2_YvkedPJ}7##bmsLWnpBw&a~Z zhTmvu@I|uWR?Tb%+!wMpw5|eg)@F@yfzZzgxYbyla1Q@;p;mZ*)~5u4n8q;Df_O6% z_uQ97dbbFz>G7m-Hs;ddO**TL%G__RN&Ci)K5l3; z;D|IqGfIw!Bmg}Dogs}?W?fsJY-lH;Ml?K>w5ajIF$aY7UBtg_j@+W2zhsGb%H)^% zRXJN6BDRZ(>&I<;S0n30PH;6ssBw>A>OLdwjlbyLF4MJDu0cMU+kHx&RA_m?KThkq zulgmjO^kcH7^T_(Jj68w3+zcYX#p- z^T&-wfE#c}Q^|gd?$0^5IR!;W%WK<0z>elxv;7bg89eDvND69WRag!O8Qv!PHbv4I zXukB(rFRZ4-b3q^@}eI3KgysF5Z9&oG#kmAnITgYnq8p1JF2-z4n5RhMrhhz`G7$0 z%`o26svUQ_pF1M#U$NV{Vf4wtfX209TK6|7&AaoZ4_L(|Zjz<)~%|og16HF0B*f_w$gqvA4x7Xv;yk zF+Vzd$Yol9xiJ&Ou*~x73SLA^g>{DLQ%kZqMX@FX=w=ERep!1fZ`PFtnHxGKn!RVl zibp3vE0{%@?dZ_;yTC67lSd8kqYt8#9I-` zXSq`zi*7)B43L=HkR+K-N6rR#(i{4$Zm%TQQCvk4Vw%-qQ)33tjMx;Frph$ZklsWe z*nYkO$iZ*2({~ECy^_msG`&@Z28FGJ7ikAAmFkh3i;Rk5NWRQb1}>UrTi939mK0Gk zY^g61)b>#nB6PYXbu^)MafI`@I1p?%uE>La|V1G%cdZXfQ2RfZgC9 z+9*iXzHs?RGwp_w6exD|-EK5_Qi; z-bU8+oTOn=?gSGO3_rvuGo*Q5V*!*36qij@9m#7aCiq^Bz z$?rqNAMH&a@-QUimT5NGj%bvyFvhpN(6UTnatJPsn#mVId((-|@taVo;f{S!Pc=q> zPI*kUW=1QQH?#MgXVnU8B`SgD)TGtDnR>Qwvj@RW-@)3Sg)>uQZK&ZKKSL>5e8L>a zd~A;Cm=TYS8YfQ;D(vd8kAsmKh$j}7F7aswj3`-=mG(A6j=J_Qr|WEVl%!JeyI+NU zN?4ujB3bMFb<56}TMf%!s*={~44Fw-P1eK~Hy_%CV5g?u2wtilNQFQsPzZ<=yeD~7 zoQ;X&Z>1cmrit}{B2b;hD3G_)T+{lt6iDR&6f8Os&R3# zpxqJU##HuvdMRN_acWCLDpN9(-jzJt7mV|=WCphVQIjOV%B0{$DI~)0S9teQ3TOeW z)(`CA!LpG%t)mFM8(dSsXS~wq&)SaM`B$MNX^yftW)^#2?+#^R76PtY>v^4gRCq^4n?omtm!;t?%JitK}1ut4PEZ+BtVjT_(Pa-&L~A|%DjD>(1+ z+%fh+IB?>0{`@yg3_r8O88dB8|I<{-O-!s~Px0&FLh$TAgxJ>$c-f<6)R8iW4trH* zy4?+M(_+IeT0-4@Bg#ULSU2T?bB&FIhSrRUic|Z7EV#3fMr=8gUQt^OSJoERtEy`S zv8F!zDUm|frtIY+ru+tS5WwPIA1HKoX;>h1z8Q5@7>!%`)1A;M{u|eoD+#XIxz*Vx zSve`)^WdAy&V=*7_l#b_vGtvSpK}&H!TT0e23l63zQvL?{d#&VNnm;;`G}fpKfI1S zPSO))jgBjlwIY`aoqsg=j8ySZz0h;pvrh%}o2wj_-4P@%nl$PZ?HIxZ-d!$ ztN=C5CW~_kFbngoZ9ge&qFaDBGe75{K$x2?9D!yNWgue?RkJu4dnX^H!zr@j=j{Ha zgHaIbYc&UPMs5YEuPk)2pDkg>q*!r6iRkiB5;&0xmG^JG|_nWj9KI;mmWeH zMoVZAhfWbg_%5vkMSvQebeTe$(I3xm{>6nv`=d)1MnT$|oUaXN&=&1=oHw1tlit|S zob5p=Fx5w?k!JZEA%YF)h-31D^73B58~IVstM1MtvP1WxlE^lcw3qy_)e=n!=jB=rIs%C?DMdybuHjimMYMP#`-qEQDMi* zHN-hH*E4~jv0FXO=SBY5ii$xy*KwmL&FzA0GVG_`&#kIjuf3az2wk(OXPtTGvwOX`iI5b+`}@s)JCktR7kBNNwQK2W-pl?h20#PQW0K0A$(`XJp$nV!Wt06=D{s2@ z|8MAfqpx{HGvwCBpVxtSrbxuli5G+ws`3Tcf(vBrHJ?34G#3e1qs`_BVsTo^G&5CE=opvl?ls6x zqc6I-d3Lyqr`$vm*80dozuMi7X4#mpGmh#zO7gYPp83`M%_sY327z&=2@~ds982uP_%V@kG|l zdn0bRGUb~Z$DcJhP3#S&`HF%$e z1|~_1u@mFVro5-~)p!OIJScW0j+0A&1q^h2hFwr&B;j@REPvct$=!BlQpj{@_9})D z(SR9ljAgFW^%Q64)Vq5CT}A8qqvLD{S!%Fl_!LPq3#F{d1KDG!RP*u@v_wx|*zoyOLGF%wf+?pNM`w zn9h1~02A{QSG2(-H$$N7y~d(C49AieqmXiq1(N)jmTP^(k=*g6b?9J!Da5Zum@Gd& zH<_nW&SWFZ$h%?zoTyZ!I&lXC2kq_ENZ16e1{scFup6t=fHBz|tSv47UYK_?vh z3EYEv)!!eHfP3*xrtR(8wGh!iO{>3XNdCpf*~bFG zTCaw2g-|8}gLK>RUi{>mWWCd>a4;?GpF1pK@zW#jptRf97iL_DWgzVnmo=&<=zoJW zV^hnay~jOGZtrbP%)_vLv+fSmi8T`@NLwvKP$#(6%I@YAt#x9W+USiZIqa{sGD$t~ zskH@WVpiyGbXzl;Pi=URUIsIUe=JVw=#cA^!wC_-%vh=6#PQkuR39|`3x_LY z(to5~kf{|;<;Gwft8iD^FwHM&aL5emR88?+qU1iS={p$EE?5t!T*-lpMdHswzz(3P z&U{y6&6SZ?lAcKX>Oy`w!I!8eEg*tkZ*u2~pVVTczJ@hY{%osfmT%J+xHjzEYeePj z7WV|G=L0sU$=J!q)Q)UDM+L`05NPU%c2(0`SM+T z&$Qbh%Fp_5FRYqy#4JAL@qi@JlXjiZ$={=eZzIG?zK$ z5Ek!jU43|q?UAi3wr8{~PxBeS-Md4Ggghn*!IXZF>XEZx*88wJTWcUsz|`+)CWSlJ z&ThRcjyv}AOizH_XcKDd!+oi}Iw(+ttRpQY;q9Slb%D6@mEsVy!N1{{SDrg$6nRg| zFC5VDPActKhpr0&yj8tsiPLWFdA$#;#DIwi6LR=Sw`fzyt}V}G_4I1>$$P1e;rL4D zYGBW*Cvbc%V=H9p?9zzl{p5K&P!?m`gR7R{T-2#&jw19+vzBVus@an5UQ$&i%}S2< z>#NvNyMAm(_0ZjaYGWDOcaELLrw4aGLi$?6_BMD@w5h#9mX5%*olY^TvF)#=6f6Zb z!^q8zx6Wl-ayM~sbOLni&nXPpjM<;RBHe-Te^n~u`jOf5og0}EvLdPL4y8AKDmgxl z0L!kLT4wK1K%hyLz(QXM!g~LNG8!a~hj{GnPF!BmSXvB3Q)<9odaNVK^Vu3^Fqi0f`ug!Y2L6qVkPPlwGii=2rA_ zYA_!<5L?SLmH>0dzRw-i_UnVP^Hq|E@#8>ok7Wcaja!#D(C-}StPYA8o$K6hMP2Mf z+#gPRkLFji2=Adp{4ExPP98_20;Vp(B$!J_xRO3v-ZQ>oLv5JHMg|h>Jmr8ogXN{i zv=V4dTS=L2jIGO98#6itx0=;RfG(_QJ2uT=NgGcAI+N!?5@;{^3sWCoW&G&=Y61-$ zPRY3hL))8km*)Gu97bAw=-wR_xAhGg*v5{=u7H&ze31}f9vKl(Kw(;B3%V4))qUmv zh-j)kEU+GE{cz}m6l8~74vj$X38Q@@{>0+e#h-nZ)f4t(Brrj!9=w|I^zGiJay$2A z)rfnZVsX%&u9!eYPkvnX?QYw=H zYU*O={xSUJg<2dheIW7b`7}X4=KO5dz-N9uup*-on;r(okP{DmN9T+!c4d?dJny%G zkur)s#WokNv}qPfYEZriFlmxg;fp7sO-i22xYF2>Gvqywv{<=F((ZAA7`h2uDl^u} zcce^ZMKENolBmMutXGKEX41E!GH;yqs&qt`n2~@jLtKSqpJVW7qCAS$J8C6yI_SKs zn9vOy`W1bz-+tB4sy#A4XIjJ_++%bl{c4<<9QphlF1Cpr3$U_|h*#9}k+@C#k+^Ty zAboL#pFgHQ*nucigAlR6fX2@K?P)w00Y<}!=PmCq%MjlZ4IuU3BXIH|$0_cZOG|L! z7#nFX>Q*ZJYq`48?rss@zeQ9471?5$K| z4N4xtpf=BAB@|cWJA)!wd94_oVAE6~awDWeUm)gTEyfY<*hE@UYi7@;qY8KNq+~bB z#>DZsvar#3TD4tiomrQkXYcWY&*+bksbc6c4cxcsGmIT8W}H3jWi}}_{)Q`Uc!PhM zn(6FO$*{0OQ8v@_m4*R|4gC_^HIllq0fxNVk@2q8TI&(jHH+L_h4|p9sLv)2wGo|9 zS_Z%1-&U#VRIUvMP#d7#&mDZrAjI^Zt64fTS?l}_?({)~&+R~;I1~KzX68n&FiP`7 zDVCt2ba_=!)eB~m=5wD^T-AAVe1eZcQ=ykS+29jB?1pM%GMi$2p{hE%skp(r$Rhe2!i9AJbNP4B|sfK}QGrw1$C=fKl*AM5}C?MbgLjP zs$+m7MVmAwD1x_)%R$clQfgZR5*P*k<-d5p0 zQ`y`E1`Rfi^xyL&&m(=m!Xl72!FFmeagFR0e`WOqH7rr>=(2 zSK&-RS4%84DLKq`Jv3pP!GL`fN4;wKxob>t3?;;&y&D<7kGw6C#JaGj|746%obI$v_VB%pYAF>p#cklNz))6vdIJneIH+hB9UoY%^c6B7B zXN}G(mRfk9(kcPvd^SMupMDgDq8D>q6X1}sSaF7cJKN#ka0q|nk7veT7wDN7k?lxA zHxaXJTi?@b6cV}6K8GrY+gAD`3{&3*j|Xz5RNGC}BH7DKlN0ZuK0c+=ayHLtNOm%fes@Tq$dinG9na!iKh z%J%~^mo&7_&E<$%{>p+r&itT|8@U!gC?GHR0OO}$(@+e1m#)$D%50IZt)Jlg7F|tx z)&6(R4~usQ`1dtG4i9x!=ogO1^7p=yU41+bB# z4ve46Lv{|$Q0Cqc*N2T`6s?abo&u4+2{KsrdW7?rn$DNB?BD&#R;;i&2R-tJNKBo! z$@^esm(e)g`s=&kqWdvVIcx6lSldWHHzFphaaEXD9R@nVugcneJ*{`EBYR@?T}`50 zY0p_T!?3l&m}y_uwdj*YlJ$RX2*luj^zeI@i7|SAdNegNxFlokB|?l#jk-g$QJ$#^ z4LK4n0!*=~h-6$5OhGNM5XLwEugO%H>_7RS^q0bSifv|$)JzSx0X!i#>Y%VWD$uUa zlO{(SjYGoB2id>c5_42s;`{TL5?Ff5ZT5cC3Ul_GaUsTHBC@Zi9bhBegAFVD5d`GS zPoa&7?KiJ`ngiLF0#vmdwwuvn5-;2SsnJU6X!Yzon`sZS4rFnK$fn1#;ULPqfuq1q ze|>IpQzR`uF`QWupI5Vf^5jR!u=S$Uza;DZtpuuIY7(ABmeOE5xeVsW#~nn5=1T}6 zC7F}I0)kJ3+}@4VFXw58bPR^TtAf^>6l$lcms+%e+ng0)f%s>ur5*Pdu^KnfR+4V# z&IsU3`$X|!1iNza2vUs|wX3O#JYL$to}JT|zo`!0t}4!eXc~%%+7cE5u=KgTfi<#M zfZ5Wwa`6!D^^t)~WMCl64S()UawXCCCfa=(U)CsOs*6J?W#YYtqe{DN!APzB@>SAG#iEJ%+9M$2aneT#U;h(Q)sHD zzT-=EmTE#U2KADaqk8bXzRpzTtlBU>Y3BeLO3s5KQXReWT;x-6B-0 zYthZJBTQM3W?(zPA`usi<%-xvtetX1k4;P$!6gvRmh$NCTQboLIsQ8`am}x$uO_iq zej#*wQKU<*6m_&qyE_sT@Hbf?MEm8~nPjv_CuWDqDB2- zt4V@aBew=+U|P?)Oz1S>=L1oI^BM50j?Dr;c ziG<)P34cpA-TM@`v9a-_p;7cJ|BCU-hR+YX$6rt0ef(bU_`4rb7p7&WgJ_&cvit^< zlYdb#m9mVm;x2)N*DyT)-h^)mrrARzr~l9AG)aa*7V!48U5>#^@v|N95m)own+U3%~23aFxU9_EtJHAV&9t-1F;@oMj1P*Uert~+tOku7n0 z2R)nmoK*_}vhtA&35~HvH*CDx(tjaNm@O9>_Y@@@OeA?5I@WIk0ij23zE^R&GgG{> zK2P}&5_o8^XVcotL+HX~Zy~x|5v)Sw@1>*7bLSOGapn)6YkWex#dY?-YkyDVzS!aP zY3OzL=JK(V_TJ5PU$&jL4{dU!z79WsGVsT6mV_P}Ssq=9G~G3f=^I)0wOC49Y2sGB zyPM(3=2AGM;dJ}&k7|>-8Ijsz-92&iy*-_&(7*GFS0gd%lpmQllJ()fJKy2(%T{k< z4#jROq_rNuxm?oloD7s4IoZuq8phWDtdZ8bNVXD?sK$VDqRM^~Jg>aKnjLy)S@is} z;^tY!7LlhFKklBO-`n{^6+WKUEskl3Q9h{1_Ojm&Q+s`4L@zih*I>X7z@#62_*-3e z*Ve&EXl}z&@!->k?}m;)ZZiQ;Dd!{CCp%hTcK5m8#fL-s1;%kgBuakS9t_ zl4x|1Z|^SZYNz(+0r&!DUP*)S#1uF3 zTB^PY`u$+<3oeW9NJjF;K~JxmV0GKW!cjfH4n!8RA6`xM>eJY)DtaSekbhcW@9_>^ z=KaDVX*Bp_Wh1%MfylQl74z=Q1wH1rhnCn3Kh)#oyjx0+fs?H!rR%`@hRH?9eX^Iw zlyS`=lGIVbAur%gx;0!yMe6IFmdD(d3im3**Eq0SSFRg=3cTCtou(8$*JG%G!g_-hki3dE2zazX3C{4K+#}|C~`uOmh z_-8G>nl45S`n->vFb1vF;wS2urS`K2%IL>8mkdrQF&~aUyh>_pL-)PkoG&aOUwKyQ zy-;}O*Kt-~IMPe`fWi2R+Emw(tRHV3O9yQys!vZZqMv;_^LV~O*Lh-7yc;dKTM*LP zV!ttfJ(lLcNFBKh1j{HeJ(!QId4A`eHjn!2&-xHa9pB51$hdS~6egtV`I;K&=AWDKGBP(7DNbC_7dn&h$z^oL8=<`RU@l^ZG+aES5qa07hqZ zsya^oKA0pt|I789bH1VecdcTg_|}2fh#h7A$Rs7PHz}bxqs@~+2zp*W~k!pW7!+t-Z zFFWw?vpZQofQcno302(e*09D>o#C5vw%msAZg%s2e`I&(W@6OB0ejomi)-!Ok3ugh z(xlf$qqv6{)?OkKpHFxlctkind`{I?wB}NHMEU2PS(TQ9E_&q;gn6v_P)v?;>2IdT zxtMpULv=m2vvYnlB`bUGSgyp*6-JBZTlo}8_Qh|E7sVbgzOKFHcTs=q`;7iX<6u`s z1XKLjqwXGY&bOztn=r_MZir3u)}`~X;YP9RM=OmwZlAc3qCt zYtqzDVsgV#C06yh*Z!z|;`E=o)|c@9aNZs#A$qJ>=~{Ru`92rIL$qKFd*DF>LH`Zvh{P$4r_0{i57~Rg?g?4^HLqado9H7+ zVh888&PG}58m7n(HVj?%wJKP2`vUYFhelGQ3dUxOlSNdPx3-gvLmvJHRt_kho?qhW zJIebs$3qNbSKJtnI`76M`cvnV)*o^5JNoey`(dOsnAS`bS>&tj-P@S99((y?`d3Pz?cHjNif zpK#r(pT9Y)@*UHwD~YlJTNN3})!Pvyd&f|D&GojghAH{j_7NNhH}~{X?x>SoSyt;w z^iuE3Au)c2L<~0vWUkF@7xolF@fZin=UB4)> z;{0>}nv~8=y*~j&9>gHPO0K{Bj=!DZB11GfVl95;aC%Z9!Op&MC$*)@t3_wNwXy&i zBFrxdhV{+_WLV@k&o(~zd|CuUwBn2XjhnlM&@Fa8RI{UBs{J{m_2fK%*0$j7BUNu^ zyoo|xhbxZsr9Qb5dbLAgC$z=lj`2**0B;n*JTq?e6@SQk{|hlN&$c^51d%%zd$aUM z&LjKBx_ZKlg_PpTIy&c-V1H63y#?N!gRg91b11sVP6M4HSU!J!7>xVuJ8i!Y@=8N~Jq&E^Fu5q? zoSSPer9NLUD!@GOM$GGI&D8tsl)>u{?=9Ro6osf7&XS%zAPv2qZE=fv(r9 zlzdS7nB&T*0rPkUZhG7NC;=Alb&$`uZ0!XTc~H5kemwg{6{=A~qi%LBR9=)RXe|T{ zt#outc%O8qYz%qfm>TBz6m5iF5fCR2t_Hwi<1GiQ#+wA*X;(z?Tvfix+R>krS7b0*m{jk&)jr5DB$h^SLItre3 z_he(bu71INUJq;LPs|`eyY}>;-G@B*dr_;c0|6sVTM_Rwu8zizpFC-Bt$WkGrPIZ? zaGpTE#%~V)$N5( z1_zCL1q0`OG=}HXl-`D&e;_y0d#I&Br-raIAC!Gqj{qrQ)6oTF&&llJ#R>bOn9LMP{}-~- znV-&LF#Grd&W%gpf)q8rf_ndJ9pAQzB&W|N1-I_cELN~%#JMChMmx~8f+WoIsEmY^#XYoF9|>KjGx&ZpI>-y#Cykv-_x0AR zA_>3G8GWRM$I9+Cc0TA8U)!F+@SgeZrfNemx`GQlkTOchXuRHf?_|Zb`!~dXPVAD@ z2j1TnQ9i0J?I_f6uc7L^^4Brx#l9cjUmizY(J)Am^f8liT}BO5pR|jr%y{DXR8&!| zr+{qU>nnP#4S!+o;oELEH0tQ5P^8K}%~K~s+mz>zW`6dPhvN#Q|v`QGp@rEMM%fC)#!RCsd^5G#_t zwB)B5pzc89h5U!O*cIcTywv75??rfT?{+TTj+4CoJMio6IP8ZZo5L@DLZ3!WUp%Mv zJ1Vnl!C%?VYG(hEFxSwy-yfKvA$0x=KU7Ag4m`bBC%|7HBY2FbJ#Q|L;l5SKWyufDN zI~|1IsDHZ*?8eW3?Af)832|q{)4?Q|=asRmy47kisIi#rEn|PF8;Hzx=?MAX%&R9a z#$^O{Oq!&5g-GMy*4sXzDIWT1sN#6B>&Rw?+nt7PM$a)JLyq0X3)&P%W#a3LnY^g4 z_zTF$+XQoW?W|LGPjwHul9KteEy9If9&V!_I(JO~@^AF_@jHglEi=hyc}vZ24<743 z@Lk-RuvgXhd>+gC9TCOn7rrJEs&NNHzgrc3!z``+N7-xlBAbFY^;fC{2ymH?F{6nJ z+LmwdN0r(#aCI?n?;o;sI-GLO((=k##n|DQF9%j z-*isavfhTwgr8r0wqWQ!74XkLCFR3#|BdB_f0g?o+~QP(R1Nn?#xpDNrk_VEKAru^ zeM&>DLc-UcTY>EC)Y&c5vzeyiL8lye+^%kOm9UFt*VNyC-H9=@tjli+)CiOBc=WBC zYbF`Imb=?27$6M$i+pX&!&J*YP^WVJScy%cf?z~$+l#LUcP{=2$UGDEVc@{QjT-%5 z@ebZ;^h3qdCKu(B9YzU5>-R_$r@p@RbiPFyk&oRjWpX!1A}3324J37e)py6{ZthGv zT*`#)WH=30T(sW%#535|>+}?OVfD)G`q!)UV6)@H{>M(9|E4&Im^iSiq;8~SelL3N zyyR{}fz)%ykl{n6gW+lXubdsah61lkJt_WlP#MYxxLmT>R++QSa5|6syf|e?M1w(Z zf^si(iL`1hH#v5|eH>O#aGKAG*_EX{5X`wJTfbHy^H3jedf7xp^&a=#C6{?FQp@jQ z&alVN&yzPILQ=WSeY2hoxK~%N9X_ZmMtfrnebI`{zWdgya$tpb^DGrq`sAc^$bs>_ zo6hQ+MWzsQ)6Xpbk_ADY(;9=j=FyQCPXT9!?Bmr+H0Sr!Fs*YT&PDH(c}buz*-NC4 z=NLx^3R_DOHq*;z?idPQ*Gd)%3zW%N^%isCJMs7#s^C)9M4a=7an=dsk)YQqgOV$ioE>TdrI=6hF5a)51IJ z_8Q7XBt5-;+oH!eNAtSd;TYc+qBEeup)ev)SP1dFP#3*Gg^Qc)e1dj4ltG3vZ6 z7k-VgdoCGVD*ET#Qj`g_-gto}dIGVqSu!?Lpm2Z?9@z5By2V!X&ed48?{DIi7O@-V z?`uzQQf$HnXt@~LmFllCEaM5sxPVE%izk{!E_|Mbz29rl|L{14SLoH@Yct2<0|j4h zFAv>WZlK=5#yxuA_rVZ7L;SpD7ZdYVza-JDkpAaqX?)zz2b*tMwaqiOL#WzhQiy?|P%rBgK8G7T>i&sy1>f3G&WeOQPS_}PE;hi!* zD0Kxen3d%UZX za6tso9lYm}d3o-^?ZXS1FHg@O^}ll%D*5vK*BDqH&-}Lwi#1oAT1vVjxN{=}#o%sb--b6IzkFU_6F>Lrz^A-h33tr%{9;|}AN=9#R3h&D4ZvJX zx;(pHkUMnq%<5LJS(HQbjdPU^=LNMN&~0uXKiOe^T*2@E0c}8%zd!^hCX}ZC@8EN{ z&%ybFmN_cOL(Ak7nUpHQf7x z|2^)Bc27HXro_LweCN1Qm62Z^e*XkS^cJAg`70u=22*B+Mt^_MB%hKXzfArQrX8oN z8|^3QKI(ric1u2W6a_n3HfrChF|1<41Im8-+>DsZHrM=78Uqe z=CB7pl&-KL)pWY(EohXE?p(k{>`>o6DdGz`twJG>O+cg1?&BNWKHTnYJY{khrGkj8LV(ke2GjtG4s4^qQ2lLbzaz{4Pm>x@D6vfFp@1YUSw{M33y{*P znjb?i?Y~-Vkr+33Kb$2_wp!lLG60hv^|$)0O!ETq?ao*oI}*#btM~a1f&>Q<6q{Tq6RCE>^zJYePDN$z9{hv7)|Q;pq|P@2Y183M#?hLgKiEt%w{Og8r$uAQ+Wd;$wM zK)w_Q2Ar&hV+8?7c=tk{AGrd%r(4^Ku!en(Es`isJM*V6oc>pbhI;@?j#1OWaJ?EFXW0Djk6O3D^Jw2=GjV1^KqdDWiXk$?lCI!> zDFW<+ueD;brrkV3cNWl6%6&1Im__6Qu7==wOOc3AAtJogDqyHtz;c6aNtlvq%ay9c zc`qy?T*Haj_0+&ah6uOQ^?|nsvz&y^aZLRy;vo+=A5Y}UmH~>3PA5J2hef+=H{7qV zJCZ~R;ApwnH{+7eCI?-X(P)2eEUVG9YxFofiTjH`AIZ-WClRvyv1qw{m6jrA(UMXv z$l@@ZnplY5LCE2LL-atojp3aB7sdnuG3FAj#{!Sfieh-8xhCI&(NU7Ij>$J zmhtRi55bkb(RXhSQlV9_WLa35yg1Q2uTQQ1#ij=Q|_GKZUlu-BK}C z@B3*6%)KNKCJUhpAlb=Fa~d<24L#M0Me#qVYqbUxH5}?USZ>2vobD$nl9u<$#cD;ab|+;eBZ(2>#8J4NOL}GMH*ZIvCSntV z6vA(-Ptf{Lku!Pve39650pE%RQ8N-iO-uMWWYbpHBG*VVhxgPcYfI=6_?KR%=GdB> z?Jc7MZp$1tKQsNe;ZkEQ!~f)SC!* zUr078D5Ow)tg*yts;?U#sz2R6Ub=*<9kbZFh@}om(>L?q+EX!8N{`KC0&8Ku3e&-S88j5@I5Z#0R{*T(zjEx)C^U?SXQA)UDX74 z*c%A5;>TjQ#nDmHZw!47S&F$-*tCeoMp{ax5@%z9M$b^>SRC-as#3%CX$FG#H%^LT zX)Viv;i1hQA>ugB*M*|!nP8t*J|3doxlFO=#r0#~IowIq1fsF?$a*c))SMsvS<(qy z?W&BBr7r1?bh1E)8qFO13IZ9boKzUQzZW(Tt%p!)67Uzw4a9kV_6EQ<*8ZvR9RB6H zvSGwt2)e&I`h6Y*Z2#=J-%V>bhRYg_7-BUpcA);5ajkV1Ao!p5Ta1s)3n5{WA*!S*Kb}!TI?_P%ll27QI}!Zk1qxZyW%?1hSOeB)$Y;`<{osEe7D-4{`ijS zNi&aUi#Lbn1)QgeUj@<|@^>Jnl5U^m9wiSB>nzk$GvEEM>7ug+q zOLz9Lg|G{4iNLiE*X1v7wKs)%Xci{-XLFW00TCHY=zaqW90C!^`0Qy0Qz&_z3trSh z#q^fkx6#;%ZUV*T+!b&fbUWtjF>k{ZZP4VB1stc9Y)A9AsG^=Fq9sZT3G`Y`THM!U z#Hpj}M5iAwTWPZ};Z?WCifV$fVk{Qpe10U9;o6M#p25kzrawX6!RaA6$4ZYx99?$) zb2kFTnSkp-@1ZuDpl>7!7kU!N)apxMf)_o>kfsk;0yTp?NR{Zr2)PTb`sS+v8uQIJ zy`V(qZ@NVA-L4+ZRLN?X7$OOV@L5A$LKYq(-zshF42GCoIy+`?k0DDYVPDAxO#CTX z;L9kWO-a6YZAqm~MT+a^^+#^H;s+XtAv(~()>AGrzi zDC+&z-qaJ)UxIJR=&?`aRSYTIo7#EoT9d3Sa>U8^>ZXPd+O2spERcqd^%z=by4X#ZCN z*x(&^_fd@AI?34Uc-b`41WZ0}jpPV!GfA{0m_reN{L151jC^VT#2A+KR&KKF2Um-u z1H&pUV9MCxryGFMphYn!JZ>77c-QRo$FYKbR1(nyj;lv4XZ@d2S_K*7c$yK?r8J@{BD6>`H5wdn{+f_W{lLrp%8$}A+iT}t z@*AI>7h3ABa%9FOYr!TYrJ&^e?@CZPdN^)?Tl=G?WVo>$_N<_r>)@F4c0c?+1u6+{fV>wi{p#q53E2qumad8eysoPoSEPjTn;OEEd z;UBW_oJL=@e0r)?4=nWi9{m8kPWI=<9Lfg70qo8U@T2b^{d zdN@h2Tn|A`0F0Os5IW9Nn2am8*yd>VU7y;!=tcvfz$_7ON6xn;f^KHK-s1;d9L6nb zU^|D+$tr>mY0e)hx;FQN*}8oMY$~w{mMxu16;coKmOVAF7`@OpB_A<~u>oKw!R|#u z9x^{tskt%91^BLFh@3lBbGXQau47^pvP!o*dOCp0g zIs9B1g@AJ|&Ad}r&@JLZyANSt4wvavkndc53O;j60$I|ZJ)fh${FmWCc2pxI=J zUFLt)0&wK(W=I5z`1&3%X93@^pM3}fl4&4t{B_;o7T@X}hbBSf&0t#R3V=6gqOMBE z7PS(#oj#H^4;7BwhfR(8EUcB>gxKtde1fGeuY>SbpaCZO#y{0WKWS-}Zd8V@#d* z|Gtyy#>K9IHMeN3(viquNwI1&K@A^B@V47!RWNFGWZKHE>@!)kIry`se8FaF&EVCC z+jFC5A_?QC4lCT&{oSp2Hl9Qz1y#r1|wRbUH}CoNqaMlvG2To@gJ^|-6|sBfhPlCvllXh`Am7h<-X2)8KhT@eY64kqX0Y3 z`IH+e6s}cg@TH9P-uX&Hnx+Q|EOdFzw-Y#qScNp1>1u8DKaT)u7rTVZyzIN;=w}Ur z^p4s1g|q5Z#L?`XVoN^Iu)eC|TQZoVH3k*s*4MXM4CXTMbHyXMFE>2lxxMs3dSq}U zE3*Ws59Qt{)XJdSGo2P^Lv?}zX3gT#BrF+%kK8mef-Zk6o@3tYardL>G2=5R;beBr zA61DHbQu)S6STcolG-fsP5oNuzbKFAZSomw-Q0mJ|YAj}8~n--evQtKtwF=+dd z^+>+dQAmaa`Ns5)`zb?gR#p*kUgPMY*u#0=z(%;cYbCeIAwPJ)6JTE5Ll#tn+^_=^ zGCA@wHh-t;if~;VG3V>!6>dNKZy52}r`Re{7R`v3FSN_#@VL#yO!=kF1THoJ31lRL zX6!VlAp4aWUdo;75EwpKwuCB2g~9GA^alD;yUpE#)#z)r_0P=Vg@5NFk~lYeA4-bv zApL?*)H`eD+?^L06`CbaAF&x!v(;W@w*}ECB#~$aL)e>6;0ix@-9pBomIIjV@n9!F z3+hTZ_G)GC7J~5G&65BIKZ~9bxUmEEJf49AA3xgvJI;q;Bc`Fd0I~C1r(vVDGPO~_ zlaAQpmrnH4I6OzC$+!O&g~5hGwAO<^pAUqq0p{rtRX%dkFz8697exc#fEVehWAHv) z3Fb(7c55?~*7Nz%#_9(S${qsF9*!ezFhmARVihlP7fDVMv2X-RgCYw|Nh}DKlaq0x zka+%K=w0lEh!QP;n~@-HB4&>QxEVJD>_Mewi3FMV&8)E-Qr0lo8-2My6UekmUro6_ zil6}_yot;SH~-)$J=URJuCUj_Ip#g31Ord?OFk74F;OMzd6T0-x zoAr$1uxM_7Fi)uP9NkA*xbRr66qzpm%g@K3?4O1FY=yl3_ZY&;QCE9(D^&>V^b<17 zY+odZ@&1x=zc*(}hvEs58-4R~0CRW6FELwAF#a8${6hw!9WR8ffB{YsUy9H1>EV`t z^5xs&yaAT8Up)9d2eI>VR7y0v2ym1_^l?uwF*Q#f`eJ;m{@?pcaQNVr05zP*z5gi7 zB#LDeE3=qOH;&PSvnY|Py%~-YA>Uw{`1*wsAwrMh|0lAZP{ZkeBB&^F7xXnKUDe)1 zO8Dx3Y^9eDwN!$>Dw9K1|CDs*2k-%~T|-jJ8XsI1qn{4I@Qljw{Re*868PH|q{FTU zf6-y{>3ue7u9NP;5tLamqof3-}Azcb=J$6}RmEf1{I5_fOiQHtFJXi@q%3~dO@o#BiT8-sQO3mBtYQ5+|)FZrHAXkn#|*j(%%+v`DxZsVV<81)ek&ImNkD6`tPXAZD1ds4i1QZ zj;Kro{@J-qvZ4-*=}?^N?xbn9xYsLP!QcCnNPlZdI4}Bu1>k~}6ga3PYODX2zUNm; z8hy2Iv>7295%Xg?!|=gC=X2vvhgSH#2hRgvS8GXYh0bSH4Z*j~53J&s4xv9$G(Z{5 zIl;2UG(vX0A?nZvT42%*YCEhT+{AcKC(vQP&{}8#V0!AkEHv5jLwZ;N@U@GG1F7kt zqd=*HXnudt%mH|W5!ZeyT`HHeZhCB-F#Rro4`~g5s&?e-#Axoah9D`EiHQ1zo%km{y_5Tt}bj)CnmBVCNv|6E%_TR4# z__s(*4~X)`sLYHo)5dQ@2=z?r`MZfkdcOgZMQ$F^QS^Vxz)^(4!RlsDAFvk+Kz5>& z`}>0!0{r}3bnkcZ}`2%|h-9zti z!(g&4!JECR84U5m0XzP_EN5bNwyo@k3}-I{W3ecw2s?og?r;RCrYJh8bj2JRI6S{% z7vn`-|1!PauHu!_}B3(T#KQ?mY?}vYbg-{ab9G`s(niF3w`$LScEF<#SRLn8Jzr z-~C_Te2zY0Co3eA&7)z;7uQw&uIZW6-GoyBD5cG>+?PfhM3=4(3^a5E{$2=xBnm|Z zdCao^4kg%X4v3;9AA|qwmI+Or!gM0#vv|s$lU+& z6hEcaKW{>3O#J+Wz&aZ$Gnb;&SDS`*^-235m*lD1Ouzf6qY-m)48LQ}0azq>xj}O8 zu+J!1_xs@4Pn8kof#|y2@e!Wetiz8?82}|y@jtw7%VP1k^f3=-Biuih#9*ASHjzl$ zP~CR${3%6!GHph(=f?(3hct^sDtFG<^lDkqi8x-YsWqs=0b55*Gtq&Gnwufj>^Sp! zXf0V%J)ckWJ`RnTr9dv-?x%y*hYkjuw~U_wecf_?nr5I?S0xvZ7h!+f6A2AePRcPX z1gvI&Ic8I=XAJf6fkNUyBlK$CZmLuo0e>9h zyY2sOfq%gt9`bm%w;o{F~YVw8^fV<$s!W_gxrn4}IA4#NO=lEz~d^stfB5vuB z=d_n+1F)k2gUA9{pH`Jx9$lSLGupfOB6+jTJ57Tekwpn?9`Xj;%^bYwKs6x7%;le=_;Ur++8DZz#7b`^( zLL7gv0|ST$yLQ-=A`AfUj=vBIf$;&Br^ZWoh=NL@vz0|79xgKuk=_}QGgRD{QgsCtY4*BLbb-BvuQXnTyn%CU%d4p4S@#0)YU^k z0W9zln*kGET9;4XAz}&{vINHXRP@3fmblVj(Z`o+=BJQu_YxY~^&QxT5*aK2gJ~wZ zf&;<)x%1zz$~e0F_1c^5stF}ccyI|F&n0!>r4T3LgDozAFzqW;NDyQ9_stEi9BO(X zcne{`!3xKvS5O)+7U!3b`w*|idbX?Q!yuJ@eOS9L2(Nt=_aYQ<#gc-z31TCm=s--6 zjHUp@t2Ct94gdmdjXcTuK`%2wBcM<^D zIavjvcz~BkqBs~btf++1@Nkv_B4B;lXgZY>|8wgY5T93|W5wd^;7NH3MACHS+jv`be+mJQQ_(`TcKO`|88_w&zyTl#J4aw!0C+=`!52#ha=-6j)bm_aZ@3=;7#9_+aZi!; ztfR!Bp>LLx?pB*8-4+%8KThbAfhbqueJ~3)P;rXB280vOX&Mj)VqwlV9tmPAOoZII zC_kjWRejQ}xtk^VjD-l^C#1D4t_0JEmyN+l2Tb5+nS5e}S!Y0(z|PPCAWeji#xe5g z#(k+_Dpa2=oL9Pv;{OB>I(VTI_$%Ps-ZQMShXVrG$#TkLlU2E-4X)CR(Fcm(dw`t#Ws<_xPK|_+6%DP1{R}hbvPFy2GO{mtV$1;NOto% z&uMLs7VOBXj&<;P?@#~N#zb}YUYTai3G7YVNR{+qVkk)c1_akeKr<)>L->tYFT_2O z<*vayg)&&Q>BN~S0H+-%Tm66lC|GWsOn+>=lT3(Sp$X|Wt(<)^K5SM1PoDlrO|B*M zIfU>x-#u=ayA!}%!TT6+v9REf3@*$46~HEQod$Dh)>l9|8J)GXPq|I}1yQC+jMbNO={8;Q57tnW~rxFotn147K0^s)xPRZKZ`3ZX?!v zcY>BxuQnH~&_Lj^uL3IsKkb>@DM@Ya&EmB<0pU-TNdjjmi(S8sjtdY8JdV>W$W1q} zKWI5+JQxv(RFWYNCcakvakOsTj{>cZ!G%MZ8M}3ESvhqqrh=_FDDTwM z!^RPD%;DC;!_Xh>r-JCintTA-log9j9W#%k(hsWe)`AnqSNO1Om)}+DeMj`I2amkL zo;zb%zz(1zz5&4E0Wgo#EWkWIBl?R2<^j>Epm`^zQzdtyb@u16a6&`QxW!;gH0Y)Q z|AkOM(p;lF&KLj`B^zmMx@?$Z?{8xvW;)te&VUGuD98C)3aXhqf(C>Xx)AW^DmbX)2A&|}qx)Gsi0G*hh|Da{pPO{M&bz(3q-R5U#dMGp(CIu~99 z{Iy&uEd;_(YmroO*_{(bY~g?OmtXx^s!0-V6IP>JGwX@4rC0a7^90~ASzLIWEua`u zD2QPi{%Pje`wkhCqkHI7F zhN&n=VtR!nbL-~t-_KzA2bOs4?i%%%O3 z_jGImu5u>|wxv8$hGEk{AQJ8evz+a|$Hg$skef9q*#AE!9t7F3l)Zzz-LF*5(O5;e z3CzDogpsl8q`ibuo?mARzolLGg^Wi?K0lm)#5P|xl?YogEF2y9BoX3^`-uKVszN*j zs>Lf-fxUXn;Y{F9R4k_G^9aPj|880hM}Q*o<7@j8V0-3B*RH7olhskqeewP&Y%qaP zwfonLp!P2|3DgK;1SeauN^(Z{`kRzp4@#TyLk)nm9UkHC=7>fkJo^^I5ptoWH|%{P zR2wfF5bl4z{pBu#+$@<7;{>jvI}BT@Z7uv?BQZd5K4P!NidJBQ_l{7X2nAtN!>}cT zAeIn1oaf_44#UQ3?9#7=BhZr#O>~KH@Lr;i*bf)KHTMx{>1|FQ2ah3Ce^21Vs!v}G z9>d0pL`$k}!mw8vVOt0{lwn#Pq@UiKI|)``H^``Lo_E`f5cyv(`O+tuUGYN@;BmVV z{FvH;Aj9LPG5&++5D5q_^%NB6BE}95k-A^9>pIu>0jtdn$Mk4*i&`R$S(A!Yt29gk z9Za_fBYFl!(2Y}^!_1--A#c``$pz6u_;3otsI7wxPi^{gz=oc?=)Qe&y|t6A%h?m8 z!BoVu-jLfZV)fF*yDx*O)PI=LUlVTy{LEr!2B?QVE@__pYY(_TmgK~jR3m^@7`{q* z3`7ym!3MKS`3Z2nOTeVyu=WrPK4Ola$Wm#$iam%^QRRA~pypt&+Q4V?JLz491A|im zwg53A!&WRD2x=d(otHZdR}pZm3|wMwejG#kg@Pcx6x|58bujsD1i#gdK=LUl4c!Sg z#!(;iq-fw6qW5TTfe)MS0FS2=y$vdn#8F|eeF~MT_8PJ5-|K?UoARk{@|&Lj*QWcPV?TdFcbh_*v-?jaq8uWD2gYk1Cu3Fbos> zC;G5Ys9e-x6N9n~pjEKwRK#g=dlz33uuGi4)gtynX#^VROxoPnK1hTSOaE;`r1^9z z8rPIoZ^cS0374|gxoNrVv53@-FlRgX68#3!<;z74Lvty``2G_3#|ZLWN)Ei(JCkk% zgFW7K?ae%U9*QMGj&>_~^sP?!Vr0oxKq`HE{ZU8WlQVC)A>*spk_k9h8%OeuqnbA(ON0ga_`$5au_VHdiS;H%t^HPGFW@@T)_q4VMZ-9){yyWw z_U!@sP$K*}cBLN~lMH35t__2GW{3|0u8hjZ5hx(p3A8MZ#~xe&z31r;fJjXUP7oKh zQh`97s5;3lX@VI2UgOaaYH9H%b4gH{o1B3wz}C8^YxFg9mg>w=whcP`zJPaKfR{e8 zYXBml7`!x?T8CDZ^>op6jyGW@Kabb$lXU*a2pS6uqSRIE@C4;sb}*3=kMr1FYuuN;T&V}X5V)`tiyKJGWu!HMzcl>u&4Nbm3uz{e!fHDznnUnJMG^a?7RVyypMoV)>9x71X(E76L3EG76hTA9{7v<5;I&g zuoxnT8-m_|nUWzPDO5aZRhx=cFug3OCri zXrX6I!5R|sxOnZEY`@RJ>`@*iRpg**y4?$NfoEzsu@hu0ifUXHFki@J`pw?&yD8?5 zru#OQoezz@`!>$T4@0qv3-_`$MM{YIQq#TAhHnRQ zeWdJ3AeYefh$W_#Q(joYseTDiQcR}4F(eX$Ev1C+9b|SN63G^RkAGwmVV=G>onOy| zZREBA2fcFt@ip}MiR`OYgZ3sV#@y*BJ*7NAjW24^uqv(({*0$<#{uT?Dm;=R2)uF{ zVMya8;wKo?eHnS-3t06yO{~G|yaI!!RS*KJME-%KY-A0=>POO~i{S$njpedK3}L5q zB(g(DD?r$s0&tm0e2bKY2&C*I-;R(>Qzl}r%(AZ$Q0DC)ic z8oWPiyAizHuvp!raqUp~vsvc_2Hu#hx$2*P!``Q}31rz|=Por&+VKN9)my*0H4L^O zi16~Ev%zo_w$x!Cv>|`biyUluIGlg=#%C45XYmu3@Su_?0yWH$$jrT=X3eWll{*O1 z6L10-Ip(ahDZDh9L?TI7De-V3s~$V`-Pdgts(2p?Ki3jO+l`p^j4KhwX;P@!Z^$W1 z_9I5ur1ozQw9s9yZ^>T{kt+z|5D7zppBq<5-?1xAal=xbj7yUh2oUS=8xji23A=%# zkL+5MK9?{29)(R~CH6!AgGN#5<-nof4^o42>jE_cbFGx!#E8ost5CUqXvF2GKX=BKG3W?BQFQk89^x71q_P% z1vsAywk6=?D0-pp({K{zEo|KXQVMAx#;he#HpJZ#oXy_){hTnM@kg&H6nWye!@vWe&9#JwbuOjH-2JqVcn(&Oqxxu*u z|J#Oi9<`R?VnYA5pY+OUujY9&q)T;fCS`1uq#qa>II(+zudd`K^dKmze*!l6E=yarxO3_*21e49fF;#z*@} z4})Lu0tARuCC-C;S%bKq%BU@irf#jl%eud?bNwH`uynLw&;8~O- zb&)HcOGyDT>e$hqr>+Lp;s-;tVJyGpcvE12tgDqD^|&FkqZ+k7Q5V}hU6pQ^09*A> z0B-ooHgK))Wf7pZN3K^w$61W5s@@m}pKZq9L8dbNZ+aEe?N&SH8utX3{ba`zj}}_T zFC-6#SW;s*_I`f=??)ypF6J~AsLRWh3=L8Jg{?Q7hD#X%-gi>9%Zmj^&jOJMGqJZ7 zm{v=+|4!a4t8Mw~R}55idGm{S%KDY<3kDAbIq@J^t?&|+WJqo7tVbavzFn5QEbluI z_vi?lWlzb&tyqNLZoWWRx4T>YOEgGo&@?UPQ#3d*uieDdnK}ebp%A76n2Yv`5+K%A zTj7N%J?i;9w|`Zg!);Q@IWk%|ozSS0$`|k1PW4m14gTnRIA;-Wl(^99_J_MKgHe@l z_+%yYxo(EI;V7ICuc_D*?FfFCm(CTNLI}s}Sn7!h1+zx(aV?g7IJ!@SHx6O6K+vs4 zuF;I5H`yfgiI7*i}8)>D#D}(y(MwP9Ewo_ZV#YYFgW0x%>16{b9NA z8w9L6xvmDg+-GU)qPw;c4hdqvN6VB&qh?;zMy!qgVZ-&p@w_Rczx!?DchFCo1MG}( zl^M(2h9V`@Ju; zvSeYLR;d)6X(h_nA~Am*9@}5` ziBW@djxu^74+ch@<`7{550t>seEx7BIPrgBM*T{8QJ$`P4JTA5)t{3WT?Jhi{cK5u z?&DlMP&%u%%k$sHsps=emXr60bcK654K0x*t6;V-0!i655nb!!z zmk*u)a47V_TqeO?izY;5U${NrX;#w$uXv_NnV~wV@9;86#_$^B*pz#?T5!8edN+fK zt?Vqk?wmODt2qN9J$ADxoDW6xAri(;@wzo4`Z`R}kf`fKc*I|8srl!iYPNB%k zc`5X6??Z%GKsetb{&x{Q!(k+HO*yJDcdIPouJErfZ23D1S8HFwm(mSutEAh_D)Xs! zyQ2`gxq`ia8T@)*mESS#5fgh`Xe&dMjqC8daPtNA&T&*y5!%9e+-1`}4h^S4al7zc@yTC`r0^Fj> z%AuyrR^+y(dO`$eht=dBt{6hpjz^lhh^(#&uBUoJLIx#)zc|{-tv(ehQYXn-m^JBh z>y5Ig^~K_Wjz%PM#^f$@SSo;=L}s8dA5bAG9*PuF@Or#F_`{FdIMN^zV}IBgc%2`T zJE!*}o095G0bPfI@Q1KkZCIeqtOi@A=T3^`sC0uA z`}{qC;Y}w2!>e`HwPc3zTl zr?WC}@qFO1!ODvsny~-$S`J~Kj#Q@VMzZ9x`+HzO(RJ{6!yk#jqsK>aP0bk3E3<>| zA$E1gcgdN*N=+g(FE@E!uA4i~*3PrJj+V+3Z2Kpm-?Q`+o%PvrA)?a0>8@B8{mzX88RtlaoNl#cw$ z#2}8FLd2{3cclgQfcimXbQ1>-p`mAdcRz{NRpYoDdQKO%jI%J&&|4W+xw9aHex0P# zcbXDk5I<%{>n9dn_hCyqTm5mjTXih;<*X+a;Bef!Vx`C#f>OoLC!vo}&1w<7AQrox14D|O5K?W?={D~Z@d^j;eW zSQwmuY;(Zne#@;WQM%AoJ*TFfauT}8ecQBCqhn99*vrzlLx zQ*Vk=|4aO8uCKpcs3Fn+{!Gnegg}A$M_L0KF6pt-cO%VqejncE$}Y4#kOA*Y14Nhj(yz z3ku@GxWUXPF=tvl5qmOkdr_IA&N>>gY4`Tm6S-RkCKylU!ZehCwbgHNxF$t$yngH^567{M90NBNI>F$}ug>#R zRcW4)@A|RBVF??J3Ph$@)qUQBl)nAgkmMn{Fv8g0u0iV14tzNpZ0ip{^A8Z0wWw6o zs9gTJ|7ph=gP62sGNJpL=k&y(I!ou)AnxLKckZTZub{P;57(d+FWg=nv!6?$Knpg&BX(uYmS38zp4 zQt`OgJ9AY!;;!%HUWzc9$%VgtSb5){c=I{^0GI8wm%kS^s7s}~KTum&h7tIxf!)_K zjA)q~k62k+@xXidMS#E2_7FRnSqIWsiGqHs3+4gXSMYeXFm4-9$nJ&EzMb#nyrLQ~ zq=Q?0aR~^GaochQTDF)%>Yu*L{vTWnIej}#z zK-#(S4~Bgyt!kkJ%OS3nbN~yV_P_@Z_{7tu+b?(cw-l(7^pf&APO}&{ffp|dAV9Ia z^k%CM{d6&elL*z;cr#{alc;&?-t^M=^YMIs^);+$&tcL$%J>*kx$ zFW=YAS17;xwcyr$w0?S(CsyFUMpl*j? zEJtXvT0Yid=<{Qh+e%mZSN;vtSc0Ys$Z%*@Ahk2 z9!PS!k6KrjZ-KY}67C-kg6oeCsbrbJ5q3<}x##()plIOC=k6!Rdm`paJDWM^!;iQyDCj}3nV4KuoJ+8HY1%8XiXisy`*BxBn%KVOd(Zk|Vr#r! z%{smnMh6io!YE4L#mR=}HiA2A&D<9~YDFS5TTXQTKDi9oYA+%(>-2x-#e1jDmLAkL zrTq54+@BeluGa1oyO@xr^Vdk%SnW#{zcS#p8>2W#dCS`W>><18IWCS_@FJTBi_lfN z?T?1!qZj!Bz*oEHEzGIxJOhEKR6AePJs-6kbgs_pxveH^7_Z9J-e2gq9?u?Yn!Sme z)3Y{oeJia|ATUbdGiO1l@h&%Uxiir25o5fRh0|}+^;f0X)tpt8W{E_L(vjrzt!B>W zMxm+Gbs!pf+!e=Chs>FHP09<{VhKWDW~QMnmf|yOV8}y%Qk{6A3j-ss<0=aL*BswrtpshG!@2%R)o}IK$+!kd zKEP1YvXrK*-;grsr02>!I?3E-9xy=6FMd63?`8-s0fUhi5YSe|73zG91IEKW?||jP$}SJT$Vm zxV+sdQJiu_BW56{;-YQvWleJxU>7i2jwXliz1}TPjVVL0!M*`F4|xXh+{I*pOeFzB zDv=(byxKZnw-I?IM;47B4Xbihicy-otv-LTttDK;WtciC=+l9RGj*zKu9eRk_h79! z7RZTaF81q<(Wgh>5{2$$(p?D?>d)+sQfkfC~q(D0_&KzMYq|O?p@Yx;gN}<;(c7Ts*;dUI$G5 z5&cYKLO7PxLa&FN<>50FGhi(Xu1?Pjb6>15nGSy$zh)Y?DqpwN6mTZ#W$H2b!Z3mM zt5S={V#)hY^Q=akBLVzgm87d7y58Ketta!3lbkmpUsAW3Mw9ajd`Lvn{9&G`t90Rs zR+lsS+>UIOH2(b~md)#7@iG%m9QG7u;8MUEH4EKq^y&@|BKsR)5qN20Ce}U2WM>F3 zdwN59kcj7w8I_?Zl`tnMXM2K(Xmpx9I|wysz8RKL%HM3r};3yUMwEv;$so1M(i9TuUvEk zg5K|QlKz6T!TRe)Q22~kTDT%6wb=eL8N?+32-CnT;+(ysrP{=(ye6atSRH{6XWg94 z3W;5zqY?-yAdDi5-_%X8{wWE=hEv7jYC2n=>34A9-D=EB-y;rZL^_+Zet;$F=eF~|)+HZfg3nFIVOp~_ z`s3dQ-J`!}oC#bvctJ8^vxsZhXa9@}t}K4LM0meE4Q!Rk+C_@UeswoeyQ2D8o7U^k zX5wdZC_|L;Q(uzWGtRuiR1M8v_He4!GIejrD4F4TL2AetR=o9G=DnFlvR6`758gXb zq9{?_v*dUUO&!iR)iJZ;tnacV4EIH#T`^RwY11NS&MiyLm7umK^>RSctXwuOdi`-ZHl#pyNh(#kZR; z_7BL>Cgn+;>ku$9-fqp?l{Eh&)6a16#C`>(@o&3D$+eA)X=qqG_kD@SINT?aytN%o zY}U}+Rz^_U9wp+=vi{ARc8l`FfWt!@emp(WWB*{Mc|Vv6L%IHw}&dujsiqO6>2k=@pWO0wqkOPSLD?1fSu^Aje>kTD}W2dC&u_Pn4W_ zWd4=%T)L9ka!r0OH)388w!}>-qW~8J`7rzUbYj)B2+N^1N?Koo0hGgW{kX)wPs)qb zaNo62Hy8~o(nhQ2US=_Tb<$X26?n^?Xn^$NS)a#lg z(OXT)E6rG$>K!N<%oFH8CpYQ+JeB-t4kUi}s#CtIJ*wZ|ls?Rb-oItEP^9y}<*?6} z9QmQa5mPhQ;mm-YsA|r-5u1t>uEUx(CbQU_N68KEDYEU#b9RQi{@Ac-Gm_t1)PpVN z9BzUuh$kPPefA?IFf2*F)}J9XigRAz`h|BX$8f<*s~E;n1KAjCYO@osGCF_jY&-_D zpYU7OUY0WhS<&A`oq>s1`{0HC{bHr)6u#3sE_9<#uwFmP;NJz%j;SKw<#{F;4x0`d zDvu(ms@8?zFORm_@J5DIRncs1wC;_i@WL(nOl?}Ygkznl1QH(^HX1)J5wnwp@_Uwokg?gi=UnWQ5`$V}D=mZYl+z2PINVhy$Kr6=VK2zVo;T;z+b1_U49 z@teaS1wqnFLQkTC>`zQTQf`Ec)r+{-hpQJgF_3!t4EoxFEofJT8F)9@D1@Ya+~$wN zuwCn3L@$sP;Iu_02TN>3&85RLjOiU?T6WE)V{+ z{_D{}V|3^O=;Oo!+qYS`kQEcXb{31aRcBb`&-n=4NFI}2HCsG+E}?Tu4CFT3_9%B` z?LU*zX+u5515a6zahqF^42iQhh!MtOaN}IHy6_^R@NF@yjIY?P)wZi6YQL~JRw+|I z#X@?P(%6P7(Aga&46IQ5BKo3Pf4WBp{mAVf&!ELn9>~~WqvFzEjA)bkkvTuc{^$6> zGny8MA;4NMrFv7D&OchZXxYtUV@)B6eAMRh{(`P!{}+Ow3zekf&V;s9J_7~-LJ|F( z@O&{JQT2WT9n1WE< zw5cv%%AYNAsh$;Ud=p5BFgc>}djhV58Rtm|^<^1BnIe>>iNPZhVp==_ zmk{_0Du9hUJc7Uxe9?`frIhK1;EJ!Eg{@3}^ID7fJXI30U{D>!@52M+)YF5W+N1B& z#Hm!NLFoFc^Tj#zU>mcQa(q+~DLTkYPdq^s^Pcixa_a=6_a1orIXbVfA{5D0;>i(N zilPN$zXiS)9+H(iJA6+?ue9Qw+q2JDE0|7YnKhieVfoSiXzv57n%Gq;{z5Z->mr zm}P~>JQMonhN$cwZ}F{32Q5tIf8Y@8F{yTD&aZe3e3-UK{vB zO&M2N2<4>U+hOBKZ9x}|SC4_auu|#x70W>nW>;E(=bk+0{V(Ot9f72p?0#fo?;#U& zjbRc?WK$v)pO^pIB=92!@6HG1i#UnTf0Ts+JaqnykwPV79jCMcyIIWiN`lihD)d>v zs*(ZM>ce15g%BbMFE+|NrVDn^jEl@W`cVx1Gb z4`!RQ4#@>w54ZRt$uy=lHcA-V>7|xldW8|0?MeZZ#q;@Xk_73rc0ZXvphEsiG-WK} z&?FL3mU3WW)WRcMZWj+YgE6NY>Q6p>1N}~S5{KXE6glc z0$mw?7ZNL)jk3-7kpzy1c@pkQEp9T~*maNJI`c^yiXtryHTf!ePFBhh`C(36M9R(E zi)KaQ+tw;=Mh>4m>t)aoqMY`}0(pq*B0`L6H1VU5hl|xIU2!tTOa%(Ln8*vaWij%C zSD&Z~BvzGC>1HJyW;J`UC*X$AMZ(DSGbqDprr{2liOY?e9U0--da>;(V{{XQr?NFN zDB;%sDH*+Iq!XEFu;^tr^hxx+D9oS?WeV4vcWo~4j?orGJ-a6U8b-YE_o+lOT^svb&65xM@2 zmgC3r78xu>Ajr~aOjC=(!f_jtkkXC$Is(XD3-7Q*Y+@S4opL3!zl5Wg4<8dkm;HC< zX>{OKgje$g-TvJ*e+iUuHOx=^eVn77LifQT-L3m^b{|qe#%MXzb;em`rc$*KU(F#bQQ||t4uF>~Iv1-s1zs#J08`2;XMMgpmSa5Di zCKYlo-J5T+BWVb@Ogh~dG^V76byHyMD+0zwbU{IVNwFEiGNo2I9>+c41Md_|8d0eic35_-z|;`U45kSQXOOO?yyR z$8AkaSR|In5Y<};ng@n*^G;dfT|9)Ip1yPi@KG2ua92OXuNQx3ua;RUOo0!L_#%Sy zi=2`MVg5_prZBQWDt9F0RB_Ry!Pb1Z^xC1xb`&obpTEp~M59P#hQgyCwoR~`0bok>ipmI#l_)b1*nME?kbrXcd;hX)r|fd7b`s4z(WKu zFHCGTZkGmLoIex(p(Nxl)BE=bNMEad?qn?oWvfz)oJ^^5&ztS;LQHuxn7{@xb(yF| zZEpzWoLxz9S$>t0*=wZ(@n_kv(Zb?FFg@{DAjH|&5T|`+NW^Jmt&l`w(NsRfarEbN z2`5H@96bIHk#Ise5_aYSF_DJjuKSqN-3;-_it==NMI*|vejSZCAGa>A`Z%&SMJoUP z39{74v|ln_VGNih(MERRSZc*$^FNHox`RhO7Dn+(|kN=uwQM21^3k1UhGb`q)f4Y?y%%EUEEhz znR9L$?SSo%OFr|ZO59Z^3s)?YA|6<;*mm0ApJ zv0Ycd_xFMXn|Y4%>+gphUyhYcVb+T5LP+r9sCK1x#)`_xWG0Vkor>SmUYue6jBUVf z7*}Rfgw$|}NOjKqZFVxIgh5u{ZJpP(E*rIDYaOSYmLo70Mk<+Yefppo6%EO&Y;*Lm z%4(i7A6?syR3_Kwa^EmLFVtiPK1kJ z&6Q_DZD!*iP6w%Lc40dup{}TuB2u)g-hWI5Lm?NKeNQUd?q1;Y1*^2n71+HYzW?@X zK2x!0wv{$uyH8rJ{B^9U(g)%?!#a}E=z(G~nT`5Mzd4S*aeBwidSZ(&b9PZQ zI`LmDi1oV1glE%^B0;4){YJL({Y#Ft2j1S8J~%`R^#ImPmeXxh20NVAXe=#FXE3?I zfYu7#VxmJaFthpDW+Ci80f)yjfe`iSVi)pKpuo9NdHMz8T`+?KFcd$Tn}&agB2q(8 z;vN?4hmz2z`F+SNnHNM5d~!(v%*oWdDwBy$@k{r@;k2^Qsoh{nVN| zF1-22BYgiVrh&h(Dm*7r;F`{DHVIs z*r3F1Ryy|-Y5ML?ysrvdP)++lXie;xrf;E%Fa@esK54iqVk0d^&;4+b8e%{prd zxn1cph+7HcL&WI(C#|Sj1rs(0T;%zv22sGMD@2(3!5Z$eyqZ~_!i+*y6Bw2ZA$ws3 zFi0r|O_4Mn;H!07R^Mype6yPFE&q*}_jTYkDR!_sDK^2dXM8>NIMMLARgp=G4#PO( zw*VguT%6&=wK6|mh6I(V+1M*h;7wuHCV&#DXUAV^lRGQx6RCH@8%{jXE(gEQ=j z=*&hHI3W$4M?UjvD&0~o1YSEThJir#vBIG9wieF5~BC{_KrPGh%DpITs z6w04<7%+W^1O|`xnHU@3KbCoXLnpw8qhpVFiS1qfdDEILdIvKLzMNTBGh!GosC+A+ zl`dvC5pZsvF6Nf4f`ADH7TMihZSa-tc(IF!&!N4~vcKIqKtl3n^o&Of;uAOhn_iD0 zvt{gH7`ah#WbBOUIFzo@&}0x}r3{Du1Zd;0Sz|XBGJZ#E@L^}KIs?2vGjV3@%)AvQ ztyL<E7=T z3p%X9_gBsJe;MMG%<%NSv*CDFiPD{>IFkZijNPDfI?3I2(+dzBfvfSk zFIMVVY`SiCHzsXj;z#fS8 z$^F2NbH7wIJdu+-LyO^h`G#Ov^_Pw#T{|sJMh>~g@bh#6A^R^4(Iaaj4g+)5%G&Oy zyZHRCN@iu*O{K%Yun>*Qx)?HYs<)=C*?{SOew#FP8V}%Y-iP9VpR;{H%r#sGb}pxl zaWqhd&fi})yNx?;lhIX~|9t}BIqzafJO>E%b5*%Jr#qhR4r~G9s?NYb=O1q}+rh+` zkwa_}|InahMwg@ej*S}FuCGpmxi77Lh1?(6Q3ahyd#;8Q zhiEZye^IT8w*i-bG`}aNbt6SIKO6y?kIvNw`<2f>l0@>dchPSn8TtCirFAKr#82)F zuPGBrlYzz`0U1N7B83=3Euo7fP0TS=;-Q$!NAAtkA;4Do?I@Y=p;`H~cgB2i)T#G}W{9iRY>ZW%nrTtM=i3hffbuxAEyZqVu z7c4S)Yv4`t$lhvZ7YlCPhQvpjl8@HQA@?q?YV_*5lR4t`u-cuh%EA~aVwB8Kds2sM zqF6rv^CmQJxifHqhZP8yyx?J@NNq(%M@{{=pWrb**b^QzTAV_4 zy%O5(t$N(D;Ob#Om)t`OOc|@^a&wZ-znCL4hLi~S*@AYj&vQ)t+Jx76?uGH8A7F&+ zzC+54{<1L`U!v*(Kim#Oz-l;+^SYV~JnmFar4kP^kV*c60>Enmgq!va;jrqEj3Ze) z9bjneI$fcz)79GBfU0eI>9_RV_p`f*1C4*%r;n&@UVA!CLAP(gCz!6}7;Jn-gi9Cu z827(pibc{S7vvVHMev$crxEpB>;iPn@|5a8eAt%T^I9d!O{R-c%EkO2l~z^$1cd4D#- zt$r|Drw(xc(T!Be;&b3T-o~g21%kBfRn;f<;S zS03;P8zBD;M-JbC4c&Q2Y70rT9J;6hPmVbSfMxm&UJ>$WoPmW1pW%BoZ^x`N`1?!3 zz$g!m|5v_pU(WeU=3>7x;k77yHGpU)1h#c?BCf{**7z`6(S~aZ1d462=46Qjz)IuA zKD>*guuW|oBY;ovaQg4bNi~gq-Q;(k(+Wcgub>CEw}Oz0*ER_Nw$!y3@1h-NvVgtM zs3I01PVeY-SDk8=JInZ*pRbCA@?RR4nA+mJjQJ=_-^}6e`uKPtx16Fv$t=@;@Z6Nn z|I{RhMUgRsnDK9bJ_ZoO5_{+f#G~3hck;0)MREZuxUvX9gS;enJT}g->iVZ`LFV+1 zhZB|c5AtUjZJ+XAA%PoEPqh+qUkBc_4nFk{ygXG6z|NqOjCZGro5JBUHL(es{>>&D z$m|(Ahntq+`r=N_-_scj0{$H6_?yLdg80rSNbrpDRfCgiRN8+YDyl3qjfS4R?#ap}6`KQBbbNa!!dQ&SOLN9#1=s5~N zku8&YzO}%DbJIgtVXtQ5W~KY&h?*flOK38fDV0Fzk>I+i)-L}wsYvZ&=D$VQ)Q2T{ zBNRO}$dN%Ty!j>Yy^`5sHp3ZQ{H8osyP1Iz;B6|2p-*nqg06)wh5|u1?wFgNj*Fcq z<%xKIa#(EhSd1lKIE@FLjE+2)!#`b`a)Ed_gLt8G61E61lpW+h?!_X0C+58N6Exrf zac+ytLd^LDf!J2(^>S0)^4oOa?*%a+473NmE;&Vk<5&S4Y}BE@&bU=zH;KXUziZ5d z10_IqL&Rm0%K_mdr!`MfGBas5|CRd^ETgbJocm&%Dt;Ar@WM*89#e2}0+4uZQ>WqQ z68DF%_I57do^kAFK4s+zd)iha03r6k<;OP$f0R|!_MPHD49W<$jNh7)OXf#8DB)3n zl@Sjj4OB{L{sn=%(0kUXDVL0v1^-F-Im#oZ&o!>uHVF&kbW3Vj_H-k~_Z zKknAQ3G+YS&I4?W;0iC8eHO*Ma>aKgn4NOt`*D|3%W}YhisT1u6u5EFu@)jmi$wo; z?N0O@c0WIDUoE($E}V3bYT9ra^JHQRZ{qO2-Bfbht_a_bmE!s*QoGsTp^}j(b@aCx zlMwAEe(h6cbp}c}A^`8iALIdY<>ta+IFij-SJ0x8#pXd)>}xe2bUr$IINvlv*=o|f z%;~U<@Nd591Ea@Q`vI6-a^F+VNQ4}S23+jc>OJz$8uS(VF8gn1sB$TDLGlgrLEb&G zzoFMJKa%VT<}MVH$vjB&TQ^{)g61&D`5<-ZgA3N%nSk%L{+JZ1M__FD=i6qW9jcRI zg2?7M|I@T&vH8!hOh4R@SgSI>h_1u4-uoUew_q)Qb@;8;8E{EQsju@!&n#wZzviZ#1n50>L?Rg!7W;haER5^P}gJK5V2k93?jR z#!dP5MlcyS@AX?9ldDXPR;chsl*6yUrNuB)R^{Qld$8R?KcRimP30S5>BbKw!B_L$ zjOIhS1yqzYxChzBu7>i^wnNjvqvoHr8mVLz9#wSy+I0a{x(*|ptzVCZ-SLyj_1aMbJH`)9QCsDLQ2%&?w=+yG zmHZ_Xet)24KwtRu$u<0?8o47a; zIJ7Sqgf=&80%QWtxj%)3OyblY;{CxVtn{_+0g;gAw@uBjeWCia`CM8IRKo8mtC)x<=Xq3?l0dC504Dpk0oQDu_v{AXmTl(WNB5M(3+m^aSVP|>?@_S&O18zOF9y@)`KRq@ zejX90QSRO4L2TppYaMDazXtWTYNhHwatWaT_R9LZkx`wUk4t`@hHKn}r@R4Ji~c^O z(_u1P5|BWQ3=D4&MYI4d^{Ul%N!Kf^f<$GB4{RoV5g@L3H)WY;K^+FO`!CIpp=aU+ zUMN^vL`R0}>U*k0xv$$~8+6CM8Ne6VU^CVV(aB`U_yViT&h#12e13@6J8Uyv*mHZ% zt*+&-BQPzeSS+nFWJ&|iQU1DO@F7mwAK!mRL45fNO2lo}p#!BsM#%}2g6=XWVYx$; zRAOP7tgn9c$Kzv$mLmW}-awdSi1Z#}m}%o3)>jxDMr3zUGdc}t*+hd7jwOY6*=NCp6D~6oD;(g}p_N$XS&yrc*m@a)vsB_JUXXR=vJ+ zzw`CD)A{sW@FT{#y_h)YYZrUJF$+*Dc!ZSvj>klgoxvjD`wu*55SIR+r`(Jw0ffOYHm(vD1rexLHcdQgqZ<)ZXo`-x{Lx zm&cRkvEqCT|8T(bC%s9yIAN$@tV$L|H~PDPB^Hi7vyYILTVED`@q=%&o9w-tkB^a&MV9lbsUn@>ALjI zka7;-LufpZD1HrbMU>ZJQXNWE{E2|te!1X?a!oGS_;2aEF)KU0tFchfqEhG9QKBrI>D}RAa4+Nb`CZf=F5xeb4X;O5;_DQ`>ET zhd>GYgz?clc`{rg_^$RVNseWZasV@>3Owbi`4(OjmV32jJa}iDa@EK{QgE2ewu!_o z`FrudfSWsA0lSLZm8KW-_zcjp=6jg2Tc=H(`z~aYj52I7O9j+u=YO3(8}_1}_K(1} zs42~OfG?V z@}~XPTD47U(e!F2N)9R#wnab}iY>Bf~b^oAT=rWC=0(vu_n;keYj zqzvJDIq)-h8(nhj=7bznXmNwZ;NBpxkq?NC9)WYzZ-;2Xy58Au^uyF}V{l%O5z2cu z5tuw0abWK3-GgHGBY9gO0%hqHU5@mRB&?HGIh0J2@TqjMS~{<=HUQ*mKi)U=VetZT z!`(UF)E`~`@W<|CIj8bKb6>dE!|C8cXxGJ*stZT%`oG5VSoutu39ux(^CMJb)i_Xa z@jFm=A>yXTRF`yi$793m=~VqAtBL;M$Dy3NGI>tONb_nQ9n z!hU7$_-G8Tuw0>9i`_6c2Gmqc5vfTRF`<4}WDzOn55OoP;k(LI+b&acAITMsN$*;i zwq9&rp<49JRJ46Rn<4duikuA5r_SA|c&&n>(|XRgrzjQ+lt}Exe~JS3KXz%dU!3B* z#basl#I+e=$$EuZ6R$)^rG5YRZN$u62}1WTyOC0P;`qfM5J z{pv1R68dzzukMu8>;+kLa1cvPj~&Za{3hoqnZvNNdGAT;l<|0cM(u0HkNVWL#J z1w;04R5BJN36FJLk)+6K0ejU1Km9fVrFr>aaw2+3QU~8pn;cWyYI0>F29dPaZ}oj# zhNtA9ZJQaGDOeZ(mPC`;%%2{QLl-{5w{cH~ztfZuCKO7`3LfSEV?ep;yz1+|nXXu6 z`7hsE8P{F)EUrlikV7slxGL&}@?_CBvH}7;XJY_|{l4}=zTq!mD3WXLqJTP`;jVS1LDOvUxJO!xGu0sX=gHZ5ySE!#cU{e!ArT zPF*#bA5HkKDNU7{iqk9Xj2n-36$MU^0XqkS$&UxSz0M;rorJu+PeHLq&-H6&l+vdO z4@62DtBh4ouQ2!-2V(f9NjRRDli?M{eDR7_#U>}a4;e%{uhNV0QFw`12Sm0}B4rWF1l&(^rKebk4bcP~eABqZy|d?0^B*QGs)Qe92sor( zVYPuu{Vbh(|QAma4>9)EPD7!4daN;}ARkSPD3(6Sz{y zpoFU}q=>N2D@RcN@^#6jS}{jb2tUUe>DO3m%0og(@Z%+ix&%>v0iBioic%8 z9ybipisbz}WRZrA6j3xbS{x$ywKOrEe&Oja>)H}BhEeTx*o5cvD6}%udUPxccC@l7 zvPDApwFDVIaZ58%M5OA(y4!v^eN?3M&OAB{!_s>AV~5HW z&|fTb!jMHD=3NpT)~JKi8S;3i`@|S5gYr5>>Xads2aez~Lv=o;N^9Cr?ePc10ZG~+ zimNvFV0Oe`CPNgm&^Ue>Xa<#C_6nN*lfyUhQUnH@QiQH`#ZFn1iHDvH=3#6&C0t#U zpe`1Cry)j7;?9Rzi5otT0EX>T<~mfBXxa~MS&>p645{QStr`I$Z-ufxeYVHTzJ?)S ze+?${Sh;z9RC30$3*p=Yb~H)}O_ru1YD&1TRn6<$OlkKn1nw%M7l%e7QHT?dM?>`J zYcG{fnHz4EC&2XQWL6V;ID&AM`b+%;P}!~5RidPDQ3y278l*0FC;J2(Vsj^y%ycN= zb9WuiuO80F1GQCg-lk$rj1W_5&6;=|jJL+y^)Jcqk^XePp-IAL=Mte&4LN03U=l&{ zWNlhgZG_(dA1rZn^==w|XW+B*KTTL!q788dbp9PmI6N*((k3pAiiK4^@9&?9%S{>X zIIGBNd!&y0&2B3ag|Q+5KLI6cRi$2FtNhVXJQ~V_D$KAwaZ|V%ErfpBYCts!hud+Y zm(ZrLPOdx_A2_)S8(@hbUcNhLP;pJq?5o5cDV9Sa2$Qm4NGYuV2ap3MwOsQ+kssP^HgDU&TLwQKuCE2Cqx276#$!#8ai`!h7*2fB;`)1{&l2ZW z&Y*4by<%0biUJ3z_}x^b*h3b_Lwu$_oj|IAoeUj=42>q@8MD8&`czI9T}ndtPyBxr zk{VTnmq-q-PgAPgTQ_yP5=72o{pLr2_@C?)vT>smc-Ii8{ElgU`GW@@hguZzO(6pg zv)Bmvh(#==Ew>Invqq9BE15{1)IZh&`8Q_q0)5SOh zokb+taDv{v{A=zF@YPw03UfyjYe2fqeu7NWho}Ku357}|j6Bo)stx7autndREKy}Y zCA@Y0@8dkW_O|{Fx?Ls_m{}O1<~k8vuK=v@ge2jYYLrw8%BIE{5toTQy0>Mk>htT`(gV3+?q470!zidFbC37bkp#AcBb8_FAp8 zK`8C}aLnQWtG1yHn#|kxq6kDxZ>&$(2Lyf`E%~nScRxRUzg>%^K6LvT+nF>$f!D@b(@4isnD`i6sj#-~ri%U(Qauaa z?e27*=Lr;cnXS#E4ap47%+K^9UoSkdz^WA_c2Z$aAE?($uY5rAyZpDPM5R81dY9x0 zaW|ZEfQ%}n1PZ6o#Pok4dkrQT=bf8IotHl9d~>1AcaG_rh4p46B026&RnC4oz#o)HfC~Q>bo>UL=~HxsWO)e9us`$ zy_xdN`x_k9nZ`2L?DQvV;xur*asQos{&~^}TMkD&&JbKUFf4{hIf$#fgzD;5DKa4u z>Kg{7%AG;ePs`aj9eFzAF?o{1hKbz+7?Ct~b^3nfL~wM-&;GAA0q!gk zV|iDP*DD42{7!c-2+2dDBT6aNm99~nK`X&m8da$Up}n1iv8(h#MP;MJxht}3u*{-iam z%&hN~+4*icfTpV9+Igwhw3Tg~4=B?S;|xU<8L$#ZhavB8u7McK)X_Wh%ide-yye23`Ly9|U=-Jc;yRCr$biDBF__z}pM zWVug|_Y2l^@i;8Gn-=Rorqyj-$`z736f&II7RTBOQM#_Qg>scB%smrSSQZ-Y|9ua1 z8Xy<*Yq&jXUD2~;yi+?f@Z8V9)hDW4pimtIk6hO?wu(~!K~d4$96uf?-VbnhKTNGF z$so^uY@4B}bq*P%3asrs)YhP9gJU--GRbaWx?=!4+LP%Sv{5uskhZ@>c&x>8yz9{j zR49qs{IJ#+TOglEbj#8UI?B8rAJ z!APWp{`bFHoTRJDQtR3x<~mq7wWeh^d%s!_XXs|=mrZoPSniRJ#sV)@=Ld^Yza;ZJ zPB+xs$>0hd1mP*M>B67XQv~e3m%uc&N+t?FQ>Lm^sAeBrTkZ_JwvQz|TNqNQ#Aew$ zZ+4tPyWN`sZR_!4d4)(~ahb2^$3*~0HI z)t~(gLn4iyC?G4_vC@wWBgkR&gwsB2t`=mpXi$^S!iZ(eIrLJwWst8Hj^j_YMn-w( z2HrF!Yl&-D0LYR^sau9r1nd4dT!FP-JKDBv1EvgUTl+27v~q8TVs@odPgXc#lzHgN z&;)ZykR`q@TLwCJ$3%wIN|XkDZ76{aK}4gh^{YFg?jPUq9A!*i>alPLho{MXJ!)A9 z$dSWIDw)mL<P?7E~=|-eMX%UbHgL>zne&F+a-}nA{Z@pN~ zT3qhkXP?=7&z{*cv(KJ6HxjV|Sg_($cR4JH&X%2B?P|%R&2HOf7O_p0M&8MK*tdrk zHPZbq2V#3RZs<3u!}7`O$L=!Uv*LWCrwelod|~g>9nd}n&$+KXBJh=%6-t!!KoT(d zv3qZ#_j`d^D22%J_Pa`NB+=@sX}IuKF2#}J4UX#nS0sh>-*xJp}kU?=od@qa3Lzxf*@;zykdR(eajaI zRR(@$W2G%ejJ7J(gK0jy^3yHva`MXtgesv#A=0rljh##A>k>*g$KDXBiVS~wKS!9o z@ua9*!5`qNXd+*3I)dS`ClcPLhdGNfl`i#%wtaIq3SJ{fN27U58BAO6RKq$fQd=9lA-eTysmQl)9sW zjf3&-y{=MvmKN7pX*tOKp87%A7N1ioc zC?3pM;u)jQZ&7E}-g~P>|7P&ZLlt>1_z-p&7pM9?Jvl;Orss-oicn6&8LytQ;2fmq zI;t^GBuwbLah&PV-VkjOnX|HKJIgOPKkm;?=X~S=hCMQ9(nXTHi_)nA?FO>Zwe|4Y zP7HM;bt`O+yo$;kc+GCtmx@F%5{7|o(db4S!IUpgrsal^g>lJ~JYS{Xk%F!I-d2iv z8%$`TwMyJlN4F#8?|>>415s0vzfK}4^QacB{^W3)4O(PL{P_IXV&sQ9C1?%k+v2k7 zr6ImkOPJ`5=H0uRROyn7zzX2PGGp+JQ-GZYHu{3$^W{}0u?(=O5H*1WJ|i(p?Yd@q zw!yXt+?t>b0@F3g;?>2%Z=7{g=uk)Rn~5B3o@}^6>COX!mC@yclcSEhRmGiBH1p^r zdPca*fYwlEeaz&U#az_(!P0w<(hSZxZO&*&vu;YvLZAcBS z@yR5vPk)|Efc#9FyfrC{UE7yhNJQZX`*`OwezxuKMQ*07wh*O9wu{w5^i-Mv<;gJ% zr?Q?2EKstSfgw2@(uYJS1gnh%AI$E|?DmsSoF%`<)+E>;5qPEngY{A*MYgl(C zZ%wv~AdZ#f1RP@vh2|un-KDt;fplqDYA601#yxFv!GP;m8Y{wrR*oXP^4v67=L*4d zZp&w1brr<#DBP}waIIlg=l1#2`C_SIyaYrt^x3r!zRuJi5VRTT0}Kccnqq+3WVJu5 zneCnShh?X|oCZa|>4_i@y|&f4$~sW4t$3pp1_&y_XBn1`FR#+sKA40fJ<_h4v>;zB z9lhpgu%Aa4s}1mnl{px{N6s#DoQ*p_2g`EWUmXT#Hq^hF%qHJ>TJ`eOL+ZGMAN?i~90S`jfCdNudTv2%u0yU3&BIEQo zvwBo^1?H?h^8MGJvuGw6&xvK}PveUp&)ND@Y=1C%sg(xM1t`P~QGDq)X`VOJgrR+7R60`C>q%>T*Il3T{sWdfl@6JCW2a0u;gfy8{A?S5mlCpR%Nz zPnMd81{Usr&+asRo_zowNOqrb46|chDP?rzJ9f+&>9Jb-@Ma)^AtJDM03&_JNLxta zk&xc~@-7;&XSE2aFg)IwyetS8^RQ@QNQC1E)NR681(!`W;QChe-hi+jF|*9a&x7ey zJvL12Qo{~wSQ>AiJVWLG=#lj_@u_5>WP5KSJHJg~O>V3<_?GEhoAJU9^A>Xk)WO{$ zx;3QQ@fv4KZ|Y7vu;YNEA_EcSYoo(DXq$N5O5+JJf>%*J+K({~dP>Hi#|?(vYicvI z!BBoaK55NcuM2*In$J&sEpXQQmdrSI@yk6ldgYf8lm#ZW_0n<~BPJS*a^)00b*0`f z!aonzElo+^(Rf}<51AWzfP;{o6DARNcvrjdpv&i#PK}~Ab0R61M|WZSyTv*>WlSr( zP8rnk25Bs_+pxO2gnVTM=b`rzHxC*WpJR$txi5TRWN(d%R9IAx6-l<$#30m&)6kMucEJfj`i~6{UqB!%RuAZ#+^&gCBN1)#twh%m&8Esc(cJvJneGK>F zqQr%}QLk}*o5;7aTdE88Y_>GH{W$5hyur}GS`fZi@tZw1^uQ?eYy8<;gt>Sd^?L(+ zcdUEjm~I(oR#^hRQamq+8s6#$+p;CucH1shK1H~UGjl=PyeTC z73%|;4r)wRc&t*d)Ff(JbyC@&*tBmt^SlnrW6?ahJ5R~XZ3yC%myD^w4Pe_Vp*EQX zl!c6mo3ItN7(64U%sBiKc+<&Y%8Omrsu>f-t~dqEVh2LZpm=UgM$r$Y=8B)$bR&p@ zu!+sI8zO@|2}XL5cLC>8@Lm;|TA(pZkib6T0OIpzxTF2%6-q|$X7I^ar6y8s@V&GO z8^Eax*;_J^&HN6Y_9%3|&wpc(RtxW?c8J3JUb|Swp+$pRqDAK8tyX;L>sXpvQcj{u`cXZ&bsMp z_rCo6^C>{Vtr%Ho$3~nTD4kD)iA&CSh8K`^gd(n&?3nJ>5Z9-Q?rOR3DyADnDCc~BUn8>sk-g0#U{GZc3#vm~_Dyb#$YZ5bn$I+EcoeT6re)4-wxw$n8n- zNJ`TL(Xt>M47^lt^Awp>F(;ZQ+JYnwV^zf_5pSCV2`lg*?jb1~+wbuCb=`r zvuGdR%8X(pwhLFi-&^|D{XIF!F}AV;6U6}Fe3Z3AS^{TY%HXCj5`^NJLAUkLYLq17 za7#ipSSWh6Ci}cto#Wu)Y^VAY;G>iXG65~!d zjENEEX_kuVElh&i1$BIzYAUDU;$P!HY!W`N6pIz$1Yt~H+ChhZsJ3wos*Nkf^zq!H zxe?5#c$=!-7E{D^Rv^yd8=-1~{BE&7fvKDpP5eS+{A+n=L-2jvF8jNZy>xg)Gs`+} z^yCYL{8bPqlyr5{1*ie^QFy2yqI<8Qd>Fnp(^VKeExd%Nu7ADs(R-^Rd#u8ycmvt+ z<1x-?z?^?)f$Rpw=9DB+?<$vM=M52zq`;iWC$fnLxY*kMGsd${)~tQ0+Qmf+LSb{Y z2t8M%^%?NV)uPFyaA}N4>Bq@3EJy4IzVtGfQ1HP}_o7I15R3o?J*NH!w}nn5S(QHg zN?~?AYTCOe9uW9cx%SJsMYm}?ZAdq*R@5~67>9{pI4W*%H8);K!~rQQ*3{Bw-BxAA zAs4*@q7yk%hA?nZXh_KUS#|gNc#*yLjXGOr?KC{2nD$yJB|PGC_fL<;q4^=v^~Em! z)!BHILZtZ}Nhm5hdqbKek|KneM9~yo262-4WH*+heYG_{B2y*cIW(79Y=GfXT+vP} zUIB9^1^Hv7B&@Accp}>p)BL11>bd>|CBbb=%j+lu*R?yMWT;9>awIliBkPO>Qm&Bp zj3BeE1b;E=f5#e`6W34=K_sG4Hb*1lMTYuUnx=Y%DR?5pNS*#|tU&Q=7J(KKx$xTUR@{Q?sc!CU zbkoRGxp)%04tp_HGD-|=atk}(g$-NKv4(F_he-QNVEK0jF6F5SF47xc(dMJ$RcLWi z4kYttC~0BK7D0qnL~x+XT^*}2VexESmr#3mO>tjE`0J9%js3nQn3`ZWE|&++>=ox0 z=4oWZLypga?a}oaq`T+O)F}sPUe}R6j#w(mBq9$Z4|l>)?_Fq*v>ThxxE&<<*t{=( zDSoyqlHSw!3lgVx+Z&VRD?OHwF^P?rZ-qPq;vavKne&R!zz-h|VO*r4t@{vSCOr4< zLqO^6Z^9eJK^3dRm8_o@+T%D{A1VftW>dA)D%o<95Nf;b7H4O6ZlLEtSSF%bQBL*c z_$dA5oZnCrgq=nGlQbY-oHNe|V99uJ5R1rYb&JWclwKJUTF2} z3=C$2goWl@iL|BOoa!rNXkSIz>M#$L3E{$vd+0y6Gwm?CgM!NgmmpNvJH~Lnud1L< z0T^#u`1)qLmcIr`7v*rRbOU=dgGaNmbqj$8Tf2^Md}UJNC)2*j)YeszWG z3|8{AiOHI<(hOii(rB`ob`Rt4Cyv83H}WCwb~n5Clrgc!Gns?melnU^fAcw>0^G?X z#?3dh4K*h53h9d>kZBeg{46_AkUUN9=pTpGEQ*%dsw^Riu61o;QSPPxw))c-Dco>E zFe$*dm0C~!lX#F)t|T86C0WTJve{VSwn z2^96HNwnE;H;9h;*&c1!{h%`|*<7W z^Lu2jwH7jseyE}z*SrW_Go-8+9c>{jhd^|JJD*?6at&sJzJypU!;3x+l?@a17uBRe zbCQ7ZBRYd%chD$_NbV>LJ@!Tu@PXZn*6$IGdr+LGQBG!quEheBcCEB~U3JXRv3*02 z^{I>Hp86VR&iqNV4WT{kZ4R-CWX(3ZJYx=2^})v|hR9D;!A;Sn;?^zldwS>rGxAWw zMU0l4Qfizf41`r!kTdC*=*XvzKh&L5a^newGCn-2S|1#F+(N-^@r1Q^p_b9Ju&l-8 zF%&W~RiIm?*OWVWJsfEiiLL3_$-5bItRIEy`qVgvG5t#>S7J>ZL`;h#=Wc zXT}k}<6}AK=4044@knhOB}z+&N)l2}N1MFB1XEW;-PFCLaDo1+yQbKDZd^Fj$Bu+E z%aBJd&E{|43iQ`pGsVuk636@{@1@|PR@g=+>g|{X4Wqbycc-M6hJ1w<2d|ZXJ`59U z0$M0~1z~?d_dS5fj|Q6xIk5Thjciu@fK5lDg<)7)v?xj@{XA_meFUEgUA?qE5qsh! zOc^c+~(SEsp8=jF1!?VIOP*P zVtE!RaY`4(j!~sJ%hIZyoxy|DO<8TVz})hckR-6nxB6}HK|(1-u&l)XA~V`YDM>l3 z_sG{anTN^nDPeUY1L*dT$?sq?mMrCAc~p1(+~euurc35hHbaYTVI@HEq){X7UZlUP z%OLfXd8yEQdPR`QUK~ot7yX6AmG?+ef|dZOigMDIO_=%`7oTC1RPN1gR*KYXc2Db~ zzvA7X7JD1bMdz4q$kY**le)ymb;#7MnTHUp8F-BRc#I+RE0TuYjGOY-NDrxh(A+lE+?TLEX)hpK4h(O| zIu23|qfaDym}~5L<)J!pn6y`u^1QQ427I=*5^>vt|EWNhBq_cS(lD($BimyW$Bz8^ z5@SjkOh(#Jyt`u$2Rj8H_Qg=EQFNO=zwID!@b$F}T{ji70zzWbr(`bv1@-8b{MM`N zz6xD-diS*#0;O`z>^F@YTmuduLZ(17;Gnqo?_0^epmhn7R2VZH`&6Jz=Yu3Ba(+TnW(ngt4O!sAtDHjX5|b0=cM)@C5GUV zJOBd`kstWUGvDzys0zZwublNo%w3)T7KLZ@B6ksTl$vdV7H%j0ZN|Akw)2$(Wr58G z0anx!=RM}ky`Wqp+5!u?zUX60{QAMk`PKMN*j01xZ^h8)G5ef?6=3wFB+7lvkIWN^M^X z|KLFEyR>Sl2;riNu?O<$ZZ&(fxYsF3`QfQG-xnh7MBwj3yzDnn+t%Likx^O=W!!%M zN`LdXE5kyZt|s(T+fb$y7|x^-8Fq8?8nQbbJ1HNgaDpg{pe9fSJ)cf~9=yF$DShHMG(Kw5a?;KFr(^aZOXbB%OQ1?C$RtZH1lYa0aj@FSGdy)K- zQrNBh?8z%B8Z-);xwIwD?@{8X6Av5(med}?UBSEx?>ysAhp%BRhjx5*4Wo1`t~%s7 z%K+R~#kZ&wPPPuK67Pd{OH49Rt4*qx9E#fuFzw=+t}XBmBjXA71ZSYiS6TT1-nkZL z@yz?{D3lovF3BN^cw-`^#ly(8D|Gi0*bN&sF!QvF;I6RnZk647-YOj!ebbBxaZjlp3KTmc6xfFoHY%s#WsX(rMNN&P0X)^8oo7E| z=^9h{AM@Ex4Bh;aiMpO&rcxLce)3sP`ihHDd&G4u%vHQ>w73a&eFO$6Yd3Cm5SH<5 zhL7CdN`Jx8vp8?x4Y3|Dfa0}th$0S6-O1tfv~uJ^C1L{$QWS=#hUN9{Dt~#2(5n9+ zTq#^MLD$Q}q(%x8k-&K)SIl%?7PEMBEbm_L8j==UdMpI1R|1pKERrn?wL14vfj7yD zm!Ivm4YJCAw0_lCx&H`{|4=<+ShA@Ldrauo11wgRP2u~C4lHKvfiFvI3<&#fXI z%DL83vu;9i=Pcd(vfB3p$Jhe;b2x6K%ft^^4s%$J13a%TB!)hB~DsH@IVP|#@67+(#N454&^eJ%84Fj~+2 z0aJT`NEFlvC-kdErj1K9D$CA*>oI@U90|`CVBvM~m~&`-*lFRi-Gcd6(o-xiak1v$d`Tr6<%v5>}!3*>rdU3H+f|AH8}vQCE??*_w(Z zFemI6VScASUX3Ditq9_FJy5pcL1*6n?=ykYZ%{OUA^m$Qk8n=2h3$^@5 zrUTE8aJ9=Ya=u6ao|<=Wh0ks`gBB*^qn(u$`{eFehG}i52{fUhQgg-ecXG>n)F%OW zL-Iirl@gdRpAA&?efQ;Aox~yJL*!Ov$UcO!8Fjc&zwT~f%)0#IPif3F?@hs!=CH7^ zPtYSIAtdA{FHcC|<}Uu9{4!AWq^qVL-cpnpMs@)#Ns~~CV>yHS{u643-d}mWn#{PcSk zeXLm!ylU2M3{BM?XCaJkn7X+m0uQnkj#q4fMQq^WKf&OFG!EtD2*6v?@Q&cUc^8Qi zrY1CmEQvi70Om+(jFh5ytC4}aURVcrL0VPjGsdJe5|_Z#xs`pt%;J`-KQ74;Qc1%q zQntgvsCLmcQAySzWIU%d#mD%E$Sz2@${F?)tE)(KL9G=V{D@VEkzwvB^AVDC!Rj9cs3pFlJ60^&yKnZ;D8aX`X4XWNY3Z;=B)*%I!MFuMKzTu71pJ()UV5f9N zED}27#jpFHbG}1x!riMCeSdy=6;Bm{_Ff)^tFnX4X5wku*_}`#EgC*oEGTas$~^b6 zksuEYU&nIdLsltSf(}8wmnbGj*y;Y45xXne8K^psxY2K^ex0hYb3ny+@%I~u zlfZPSF<96}B!6>82@!jj1~`ho4@zoCDKtY-)CNZk`uF-?b>GW-nG zXv{-oLhF~sWF5H69#I&QcTlv8@g=$ha8Wd%Ptu%`MCbUg%;UQFpQJzXkA(VJ;-EoW zu^jt81n6DG+PR~WrAUBs8dJYZ%upS&gKC-exjF26NkD8vh*}EPdoYBy&UpNdX6J_j z-ErIE7L3|>28s2O+L9g3SbWOnHS$#niPe%#bfM-Bs#T;aU-(&1;Jz+Fb-l5xF_n?3 z5!D<7JobJ1bDe!!-~S!dUHk~iTzCSr_%su>M(6DK4%1}TXZ|R>VqhQ}fY6o10n;X~ zi3tup-**EQBBH;BD4=CZ)_0OKkclLwn6cd^q=umd`$Hfok`h?iNC7U$>|k`eW@WZ zuI?YazhadVn`K7hE)5BcyZgVMQYEIH$%kL3Q;s(42A@Dhrzl*8Ze#1I{_95KKO_au zFWc5ECjgjyFZ%oi?DL}#Uh#{fcrd!wX_D9a|AkuFVN1hxZYg$^ocJQ!{*&g3`hA&U z(1*_i7Q(aHi&q#f#DWMQgoxL;N~!?oi{AYExc^YdS_)thyIX}nE(GNb7-)aJH(ws- zQZ1M$oqbm{^-59GslqghP2&Y~2!YJ;xz=XvqNo)t`i^4b^?zM0Im~WdyNb~bp}a+z z*3tVTME~$13K~LocV#f$o|r|axQEdF>(uD!(f6H2?H^kt;^+Vf{RbMoqpzv(OpOvauh@k+KqbrPw=DbbAJ0Y>-X96Iq4&pMPu#; zN;jRS&S&tf)!wvyQ+yp%*R~`iNzgghay@7MVkRVE3}^`X-H+Z|q9eJ=DNY1Bj}Aur zE5;3OY1^p?y~MwebSO=<5~5R*$7-mV-mfG$<|$$M)LYvz!IV! z%$9uxDl&2WbG^t<%J@9WPyECsXLa?mcy5DrMHJrf*iG@Q*Mb=Z_SeS;M|ekyLoNoR z#)Q&M@2S*a-kY%U4qyD39LH%?E06T&rQ!0Ubl>y@bF$pvF!KMg7$v^J72{CS3H5#s zCh*%bA6dPOj}xptsaI**@r3heqb%y0)Fm00zXO}3i;7==pA+f1*U$fz1~iwCzb{6~ z8>sawU#bX;_CfGFEy+1A#mFW<9L-CT!V_%U-ny(l=qLh~V(YgWj|M&fI<7EFuL4`! zQd#vMBv{~d9?geQ^??t)zkTwv2NXYpF2hzJE*pnSi^ocmrP9ILsB(WYZ@>8I4u08Y z?fR7XzgoD0EH3|XrpCGd$qnv4@cd&Zm7ncOe~Kk|id9&T#jsJNh?i#3E$AvA$5S$1 zF6Cq%P5>P@>x1&*W$g!5@E7A{`^J|rwxI=lkF5u@LV>9y_&iMj?y~5KW5OU|kt|sR zFi$t}Pg&8H&4-dFdmXGL{RuM5b^AJH0r=zP#G-O@#JaY|tlr1oMmtAqZ;Sc>kD}i) z{gFjC4Vu$Hs-Okn=2R|$A-B-RcqZSmKtLxKM zMPMA3Vz|tFk?+yhs{TjcW-Ytdz(idt0`q9jfFYj(_~qr>VQVRuz@95@M5;WUl#fWh^*^)Zkah%m2^8UY+{PQ<(Vo|@p2Jrj-T-13G+cWV~52={t7+Tq6O7|IchfBs2j0N0_D?b%l%?PqB(lOZv z9`T8>Ev))mAD=y zhJDNC!_Yf~`?p#56u>>^T6(qac+rFcq$_<1P&L}QfZJ~|qRh_=Y6k^}2)ASsJ%@mT ztZ(lX*^@SB>tv6dF0&L0%8ytPlWj1M4)|&Y-3^@u3}i05&L}E-FzW*ukJa1?y;t6a zjd&Mrm)4WS(5J+%pVxEOY^3qgQFb6}7AV)eozhaf%e&X(MV#qDFnR9IxH?=glJ{h5Eww9b%3P(j#v)8K%jeaoxI1lBIBo zO}ZlG6uw+w=?HBsZ|nj(VQf`)2^m- z5!<ODU&GJQ#QfSEehc7^T-MuxAx^Je zxN)8QJcu;GQu%nBB&witss}vh)V+70cF}KduovJvcIJq|yc-Sa#)J$K^>j8_tzGhZ z`u%@g9tlS9EGVFL(%%>~)Ov2WU`lyLLJ8SWz=I(*`|r=g$SF624tOp&jtRWw>r@3d zcv!jS=i1v?u3_o^#V@bYD??)Zj(23iL`%~B%CQ$zk-QBP?w+>FdfErnf&;pUsz-M} z+JWG?h-c}SiIOZX+jk-NRR5UP(R5(vf%SRZttMl&kj@tiOh#o}(oSpvCM3G|R%?em zPh8IgG1IncQ#}E<&tJm#^z~aY%k^roj&kObILM3-!E6XaDm_~_?rTU%z z2sJ1L4W|2mW78MO-bjjV!0^HaVK)NkwIZ2av4#r~+r|U>jF0;<026AJz-|a1({ond zvbg8gY>cP}SAv8YU`_`c_1`!)J#J0vNw+o;EM7; z1-y`C$Hk7x0g^_==XCfYV9p0_^Paf)V$hYS+(Tp2o2g_Aalc)^RktPPyqXzS>l2^G z`VSqyM*_6(^x^yD<4oS^)_z@E;007v2k zQZ^{YeU+TgrIydD`eNx}1y&T1aH36FoXuKdy(sVirX#$qE=EVfhx}|nV0F{qyBx4G zSK>5P?k63P?>n@6RRV6#M76-F_~Pk8Bs&YWR1ZSLWD1NDOHYqF2J`s=YsFY#C_Sqt zscFT-(bP^(E;l(Q^Sl4zSWIBeGk{oPWP;B;G|{L%!ABOJr$0V_^|l(XSWeJ=KqD13 zCQ%&6Ycpn>bDb6DY2S2GSwJ54gi?5He{Hn)!C`TAJpH-8>ZcF`$hw6q`rJ2q`z(Ip@Vp2Hx|5%Du?du@7-&o`ID!d@NILh@{kqBzjA1|T0)Y**M zK0UOaI=x_)gfd_OO97L)kQjKh*aEHudW?w4LHM%w;#2-U84`W7aP%v|3#~eznGt}< zOm{GX?_>ef{XDqBjgCt`CepF00O|qO$KY#--fFMbTr4zPkk`+b0A1{ku`4;RpU65; z8dDzz_38pQo>mH~K61SfaxHZrG40m1DX0LGX4utLo*$YTsIVHQ*)nfakUKWA$X^%~ zKeP1^+X<2iz0!S@RO4gZ8jKC5uqkHyI_oygnpm{TebJ~F0nlgwF7JHt>-mMYmn)K` zF(L~CpgAtJGcOTA?RlGX36Pa3gmBtH&#j^*QA#dn(C#I={cya{uIUW4%D^Wa)-UP- z!@M&A&Sci-sj6Xku>t2Jo8g40a`~c>@**Ohd8GZuN?%zF;NlyJg29Y-8tC1mZLPNl zaGrMKP9*~!w5x3E5&bq}3Yan}<9A^%=t9(dmjOoR1H&ZgJ6NzOyd>53~17M|`GJC=iVrl3)dXH}v`_1ll?kWvQf|%gB%C2e9W0!%cQFP<7c+p{l50Gj}nekL zX`f0WTeGBsTa5kEU=Tw;v94{*9Y!9@i;k0_&BW9j9n)P0-%)3=(Dpb~1@CjZU*j9y zDmc$bWQ#7$ZU4AHt00**28?LwG`dR`_?yCp-rx3cY_4@W9xuvLXX;qVQNNV7<+-I! zh%4;&zM`a9ePc;=8a*uCGU|{9nd+JEAOC8q;$I zJXcc3O?SSC3PsHHuS{$r%loS+J4<9Ow zjEpcdGInjBG316Jpq>8XJ-#~t)!%+ z8mD=Lg@tRF&@v8w{;VY?A*m=X&L}PAVwdOR|7JhNZD;B&bZ=MJ zdwY9(4-5>n)YW4!Ffi(&h4G5LJv}%Z+>;X%YIKCdJv|Y4`1qs4!pS*wYAQJ_ zudYt`o|YCf1)jHgcx5Hu*)#TQI5`4mP3}z%4F}_0z?i2#ejHm_$vr$gtar4ueC6fk z^FLMb;@O#*EJT;OKofG zH(@=8hi*lkHbrK*xVV};uY~_h)%G&V7lPf7Tsj87+`5I*oeEFtAe6vPjRaeL!my zN<}65eR*k#k)3_8>Dw(fw!_+5H#ts{e>lV#CF#a4*9J8wj`V{Ffp?!#=+KY08ljL>~gF#0`-zPa_9b07gAFQXz|C}|Xk z^cVhD0EYm(i<7yzGn?uE#x?-poLu2>bEp4tJu`b#oB!GM|3`t=8g6RqYGw`-adt7Y zwr8^v!}(W{t+feQhC^#+Zea~Khuu@Trzs=N=)nYIWOTE)HUs{9FfrlaIJ-Exn!3Q? z_Gacd-Z(G-tl=&&8*@+Le||U_!)=6d&VOF24P&-7w{Q{u?~9$REv^T1#BaZ3$U<|=ujK4|C@()>={u5b% zVV_rriNZ|JTVUj5fjL`yncG`1UaH8%^m~ddV2l^Hh@N+j3HA#w2o?@bKy%=&X68;# zEHIi&JraUR8N=cBF8_=WW@m0^@8k)yuy^`JWIZ^|?{+}=MW^#7eic6Y#TS3tXB7iy zLiB=vE-swYU-UOKUBdOJ2EYjal@Bz`O0D4QT{|yk`VVwa1KM%%JfB8qm?c0D__;`dTx5SfNDFJ*e~AP5 z8+Hf$0O!%()y2Wp8N{zZl^Bmp&lREFcm$T@L;KUa&d;#mnr> zu)C_#s^Bm$)!_hp|9@Kj{e{2q7yiOu_zQpGFZ_kS@E88VU-%1u;V=A!zwj6S!e96c Wf8j6ug}?Cs75q1o46g$K_(A~%qrox& literal 106322 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 Apa1{> diff --git a/files/c/bonuses/10.tar.bz2 b/files/c/bonuses/10.tar.bz2 index eb1c3914026f4f12741a5e77862468b224829962..dc6a4710eabedc14b05b5981cc549955749237f8 100644 GIT binary patch literal 234785 zcmagFbx<5W&@gXa|o#O6Loa1nc6qgovE5+UJfa0#j-Tm;xO5fl2e9yf9 zzB`jmGP9e_CY$Ue*~pqWit@=AGwT{#&JooB9Nqu@KVk24$P?gyK3@l8|d$1-d=Gzd^Nsa=>F1nh(|1=6d@I6ube|>>hfAG#^7QFAG3jKmC9+B$%(tmzS{IK7w{L z;AOy}W<50&2)P7qjK)Z!*p{*Hxz1MaK%)8#B4eIx}n*X!2?i5N0;|T)*5VnDrEuRvvUVF48kb>Md zB$^?QqU+IB5>jba`4E50US3li$pXt5?f3@%^0MEF; zUab{`Z*|vuEj?^rJiywQx9;-Kn_xXLKoHFD85-zkDBK0PS$YLYf?&X_LV+2Z<>k$K zt8IU?T7k1`^Gz4fe`6*FAL5mNj zll4F-wLB~zYVFhw2L4%xTpzbl;B?OblfAn^d0>gPcFRjx_v+P4fJf)xFUZQs2<2m`~ce$I-dS-9`Ag%E}np( za}YS#!)m5`+xYs?W)`%0dGWm2Om!^b`!E5aUIqubclo((2j49uhxHb_nY>pV$W76dbQFTsU2wgO?>P&!L?b_B=K-jgKB~W}E(X4`9eyz09ApP1hsc z&8sJr83{wyNg(j5)+2l?_$X)Fzguz$D(Juc2?Vn6(UgQH1zf$JgRXjRtNydIZ5oAq z58^Fwodgv0@Hhlt0EJ9kU1EQ1=X!|Q?2`2FhC)U@Ol-S(pZX)ey1wo_JeHn^OP-rm zm4h696eT@FV5O%($gAnqYx{C3&}es2hs~+#M?3hcrfuC`!maBb)&v>}s%=vRcGj2) zwtLip?O>4C5fiiKAecmRF+Sjb*YHh1^ecMg))$IoAunB`)fFYOd zes}Bs{@sQ~oST<6ABBH45W}3S%!ltV&q3?0dmFQ}FS`y72AwnBz^;q?iwTE%33sU5 zA`g#yGH?~R1*6f2LjIE&w3=(A=?!fk?|RM82Z2F$Q`?|+v$~hHjXyQ5Td;b+g}U?h z?hTbfVAm^X^{^cbHTCe9I4?NvcG=7~HwU)^U1}@Mz;3^;4E?*Je|htC1l_nT2d@}r z!+;m9XAiqBmlK7+#rxY|HSKMeKp_~52jq3RZ5;}M*4MXsK>W9ZN&1i7B%5svL0#aU zysafzv?0hpIpTO-NVDz^*aBHqYidaoDE_&0yrT-dU3JIds7HQO}LmxLHvCAY18 z`;RjyZJg(luN}AT|Kf|UTfkBW`cg)m`AZ4}tcy=kwG{d|2`Aa(c7_*3Q>*xtT0IKllSB zAy-=+P=DQepv$uAe~a{Wt7fbFYD&VVJa*}@6)qN8Nx&sGqLSVqnE6^j@9H`rD zZcEuJ)O-mEx-xp&Jn|JDHW=9a;9UDCtK~TMF~~7zV^&51un^gEP;CVT|9>L2|NIZLTA1~Jb#lR3vdR6%)M#D)Lp;cW-|63GEr0Dx1`|7rvHPb|D80FVVByapit zwiXhqpBZpe>Q7!izw1XgS$U7iWi4wqirwY(c%OAuqVuM;<324H_tExYLhPIjACmoh zYGSuGyjlYXV~8wIde)u*kB(>*srZO-1e%VoP#!m}jH_h;td$ti_!O{HikUGH0qwLI zdaRA`v>k{|JNSM5DX7wj@MR6OS5>sdDF6y2*(2!`_`W{Q3Yj>7S}ZB827ptGo{lrj zUXIvk0NEj)F-3+p4ULWt*&g${8dpGo5uRU%g*L2$s4Je+*_xDz8PN&tj#h>MSspGD zFgYp2YY&grKu?>2fNVMMNNd@jolQ&pc{BnwoLoU|)D*kQR;DwlKeloa9;Z*LC>$Vk z1P71HEFA_Pp^Uk6ndsKSf!MVvUVx-RpU|QgUv_}vV|=t_%8DARXbab{tHp62uu!in z{3lwHh|S`63w%ocWKeUP{#SG#)ucTv1&Q88@iU`uK*!;STjgvVy`TGsUs(Bc9zP$lZ3@5U0#JVm#i|jR zV#Iu&I)%eY(F{&Xt5>tePf#JH5M^{=)Q@Y^KHC1wv$p!r>)-L$Q|zTuG8wa=fG=Mv zZU`_+V*YIYz_A>_R6BDFyJi89$SauPOlDSwdeS9As9!q%t0Ezl>04L!*WiF9tpywpIV?r6UdssV}R8{Wx5P zdqiXyG4eu|ntFNUZXAR84^>&SQ;zbXa`+(v)VobR06NOj$$L=(KbZila!!OYvNZZw z3K~Dl0)UrS9#vm09MG5w&mz@=2hg&YM-_ArBPWd(M84RBzLfi_ewUtLbCZW}yt|A5 zSNd3LU|um_*nPH*&%N(bcF3?(51(5rA|Yqmq~EfYCXQ9=Wvxsj130T0QOX!(I2Xz2 z>dDoI!-cRj+Ru$NjQ2{n`KDTV3l7jXRE@qHds0EX0&#BhW^uw(5`5*pzau7ewG$TI z;W%#ejzS4>F57+VsPDLR^!G=pX~!uCZ(>X7V?Hbhp(r!?RJ8uyOW`ya(TmsV@;SjW zwi4Uz#R=$r{OwSRzYc$C+QA9lMMIS(HWwy7D;{M&Ttt+cuB`Gr7iM%ZLXe&27;S0ty;TsR#GkEg zLORkPmDpk&w7b}wsKnTs1p8y|g6Sv9XYx0Fa-I0KQ}lnZpA|&(4@Cc<8Gee#}>X2xV$~c;+5HepWR5 zRL9SGigTuh`&OSeBOl>R^k`TWiBgnoo_1z+LNsQa90KVBP$@oIF_~gSzxtPwpnq zkAEZfR8zhgM|)`=h|uoOK5hCan7$f2lC`*ypeiei_>B+&-HcAFaZjV$-sGD-FsxR| zz?dMild{wYW9SAKot7+Ii!a+@(psG;@YiU$<0YNgRbqmnD)1x44XptIJ@V>wC^WNjk=_}W@JNT$jtPZGN&mb zSScD8 zd)^rME!pwG_G?|8K%r60=~<9~XP_LOpe-TWBq_&SEO%f>m`WJHpzVZHxq8BQW5U|{Kzfc!NQ@ys=$ViLd82X`oo9`VXn z9$BrAo*7aGPfM*+H=Ya0B;<7VO1rgIz-9-v5uOYdWu?Jb8{V^kwO#E(E}D=>^v z=Pgd+DjU8ywnEML!0z!vroO?1^b!Ar1B*pX^2D5z5|t^Y`uA<2&IwaOA{==YU9kVG z6G%nj<@lE&+SlTPW9k&%KQ#@(i}2Mr0_U&1$2z2YO+P#pD8hXf}8N4 z$1lC4iQKT&Y1K)8k-wOD^T1M>SEJ#b#`Z;JYzw%~*Ob`Hi80SNm9?^S--oCi(Ug=f zDEwdoG60Miru6|Kn{e~rR&m=Yk$;%DN~%@4t7me`$~5TNcHh;`Qb7Z}eGHJxO>;lX9sMngPogGPZJE{3EziTY+ z*=UYn{rzPg+`>q@YJNoDrHW}4??_MQjwnwWfjEVVD9`m36~k3QjW>h$iPD za~?DG=y)DM$bH3N+LAJV+==dl`KUof&u9@x2 zaQo-^3gLTB>XrdUzS*VV z&JP8_J*6w0dHk!)_%-MeJ!YNQ2EVnMJEAk@@NS|3nJn$g9DK5s^fndc2^j4aK1?l( z2umn3xZ>tWxhww%D-p#wLJ+<9-+P^@oIjt2(9KiAI8oSwr9U-JaMPDiMbML56j@mp z88T)|k{=Cj$c&ZckfPUw>At?{zoxu2Q_Pe8^+wCvriG*UDo21|eHP=*YtDl_;{_h%lp_^PDz2=BW@b+b0D*$^DPG?p^rrRKDc z$!3?Ivc9FYHrJCf(a{Vsr0SGh(Vx`BnjG*tVLmv*9sE9mBWf5{Ps1GeLqs-;NTS=; zWp0McmvnpZtROpF1_nhGiA&Ad{=^V9!$VQ=k*hH>0;Kbu1J$TP;4BHHJi-@RD*A=| z{c4m@o{w8?vgzcd)r%t2gQG7u&YjPXshBg0av+^g>_%Pe=&x(?e|53*yNy^TSbD$B ziT@%MfIC3?Ikh9~VhGiCPp*zbAR+xQh)STq3uNmVPs2#H{dL+R#)Nru zrC=a_N%BX=2G26A>@I!RA+oMC$7L1{)XLU$Gx19~!}B!#lQXSR*2yLgmfGGk-uRDH zyK|@OgPRzXWW&rEjzXF`)+*1mnd)%|YW(eTWjd3h6(vGGfXE4QD=kf~JqoZIS0Ar9 zdJ(_aO%p#hr5%!@j+H{g(@&CU^fb2>+DzfV^^1cbOWzDdfcS4(db%D&aoHJRRQ0d< z=m80|(+`ZRi4EgS>A$^?kcxIU*VO3eyRr@q*_HdOQtTZtu-HD7JtC*07g_ehogaj; zu@K+vdyt+B(Ds=o|L#VPotCm3Vp}K0MoUK>q2hTAYLApd^+={kH>RT=2$G3oCNI!=d&V49D zApO;TEj_2xj|2l%x95X`Id`CR6qB@QcFX5!bl}?`UHV-xCNj~d0uFJh@&Ip=x1KYV z*Z@uqdboFU(~#e_X2!JBTTw!PN?xh~Pld@*VTNudG?OZ?-8CipSd%O%j<-%J=ZdnY z)n)K5F!_j?4vxJp-5tYJcRoQo@YAue9#@MWCVGqAPFWWtIxm0YpSDwCKS7srkQvh) zqQECqY#t(A@hIWB&RTma5oA7e4kYP6cz4mAo}X zOSvvQkvHTkj+KThf$F&+()R+jsd2W?G6_1PfD332BtM9&84zOP^BZTf%A4X)zpKdI z_e0KVm5g;Z-dVeeB6`YKF1<8w=a}!dza3YpSuYgnWm*D1nOL{Kvy#a+JHJ(v@eSA$ zp)0IZI~%Eq@M=^Tm>tmOzS3#0nh_8>+A@~AQZmMrhU&Du7d?h5VXtL~<*|L|9VH>% z$3%%l+>oW6uFi3ew@68dV0ThvC*ys&iEL^eA(*HKdsi7SaGWcvSBNOMQNMJ+tV3UUTCfP`)Jvq)>$Wkj_l05%Z@q z=~hYI&E%q#SFJ>omtRS!mwsRhtXOskndn0b%lDAO4MO-<*C@;`Y|%0)N%pZ=)2L59 zI&09=DK**rc_QZrIl@o4$=ut0LL$N6bldYvp6Hr1m*Van(u(a5fGJ`fm|hA|!Sy_K z$wIMxBT6(wek?3>N3^!epXf)KDSU?S;Dtro;D*iNN?WAGkLo;XTT09T!SBHyA*5Cg z-0`S1ak-XBUn3J_uX|~X&tr%=0XJlyf!FsJd~dS6wvBeSA6dg%pn$;LwLa_f!JR#! zdK)dE2n`Pfx$u?9hh;+(nmTKS>@b(nX3xSqev+gGVMy)cofw(gO+OsXkQ~YuRqF08 z38P>834}n1xmbCb{ZyX4SC~Gy^yg3c@eZE+s;`Rp7G^!Q#=#ZYrR)H`-Nb<5y;Lhw zJ4S@(@*qh_;n;6oB|>aoQ}j+NB}5#8o}u4r&pUM0L&&s}x!(*z7{L9{n|wH@g7{rG z?DVjAV=~FRcDd;q?jk*D=rnKw%r$J5tl63l?>XAU*L6%Uk-QkpMewZUd%$n()X(U+1szr zQYJcriby(G7FW`(-{ghV9V(BKTsa&SUIVuB^V)db%Y1NgzxP~P1l^z5(~Gj6N=wgd zlZRXc)8JV5Nmatyj<8N(3fod^C|?W@3u`PG^tt*WI5XXp&)fta+;M@qXBFQ*i#%P> z{K4f&yA!#O)vVzl|D~C-NgG6In0ra?=Os*aohSNOD!${>0-}#JN-ANY1 zlcW+X1$@AxO?UKL3}HPNwJIf3u8HI#|Mxm_6RA?aE=WQ@(2JBOR05hmK`?Wj?Cxd5 zhk}Ax8(q5<;H;*C3OJ@u7+2aR@+yejHz;G-UUuPq!)?t#xf%PIp^x^v-^+X+(Y+@Y z&(Hh)UZgPhX>1ts-_uz+Q|70v=LFi@Q#$_3G_mx<76);gFRDd!SW>t4Bg{xgvrQLR z(+Ynhyd|`U>qXp*XCp^NSK%W?jxVc6cEZv6yla$N-Xqt7S-}VY#yZg5)Nkye#cQok z)|S8v+XdDV4qil~`4#^I$$hm*kQJXXLZ$B3*LyGcmlOb+PZkcSLAN9E01+!LUogg~ zYp}$YDs&Dz$}o**Z7Un$3QmR30j%43HvX6Pqd+rKQI9_e&}sHiqkLasvNu7?aiW;+F36WiE8DI17& z#{Xipu?Ozk1KqNW|GNhMAcse^p-0zlnuTUZocpbgibCQ(sx(7%gW-}RWIi-F{kHIgE}oOVaW+D)qXt+hreWMXc^ZRwjP zd4$mYo@`wgLK;l?7JAO2r#s5@cAGgIF0GEAq&C}uOWM5Vc}v!yBr**}z&7_c8t2K} zOa8$@kv7jaRRb6p>mN z#w&&o|JbfVy19`XzlemZ{v(5{B%So@gkf|q;?8s=^WeMET4IQyy6veD736RM+zxqn z6_J0;KT^St5F4Yd;zf-NaXp%CG$X7Ka)>Keq^?<3$-P3ui{_MZRsfJgcT9T+Rv#K} zydU~S&jFYOFnVGN6cy#F%o6KnFkcrOTSvGLyen$X+{|s)dA3LCj!L+hNd3DinbOq|6U^8emH+nq|~O@@DEPHd%1`cQrF zRQ|vlv?8sPnN}=B#7=C67U589R&7VFsGLJF;g#NJ$zqeX0q}(9LSH-$(R@0)v~gz5 zm8@j{i~Jgc{S-ae{@VaCb!*+x4cwm3B8|;!XUET&{Mg{08QM~xn4?(olG(0k4d&J2lCr7S3 z8@ejVnpnrEWKD|0mm%M8aSFa(cME9v;dlySsZ}`X#Zdsn$wI6jKGjldrxAh*!%8&Fm8l9Rwc? z;~ut!|CQ3ue&~MgP$3FOKz>c&kYv3=p0ED+l>k>vZxZcjRNNUMTuwX<ISD z>Kx4@xeCRHG0XJ_sh;qU=PXPpS02KDmCVmOq|)(@hi&6!Kg z)r)d)!@b{iJc3q~zNb&lSS_j#%c~^)-LMvBF89W)gVmN@nBuZ>$%V!E)1L;uRm-@X zp-R+Be7x4f)7^7hro4sBFiYm*=|0}Cz>`r%BNOP|y`}A#S@OK-2Fw`#)5rcx?^RbP z*eJG6@XExJ#p^yyPG9r`8W` zN7CtOcd(b3RXh6zmBO4z`^(N0(AfnKsRePFT5^ODeC_cA{4B`v#>W~`&#an@9q-Ha#DAN-zayh_hb`h6C9xHKUYj%%PIVWg>0bb}D;qlf^HVUhS>$_O z6D*FY_hX7?KuV`$$*`p1iSV+qp}gql0Pi5aJ5TZYy#WV`U@=5JiKwbg%`MZg>7^7; zahv+xB1uSIMA<;e5%#QSersS1bi}%1EB@OvA{jpMsVjum?i0aM+5;Rj-!*^m%Q$^U znGkTbmivH*7dKl@he|baWg{a@j^6axw5bAtAm&XP&xK`Mo$2`Uq^9k`vF$zc$jRK! z<8f;3w$=2y#1C&G(u%R^_cyn*yUe7%%Pj1vd<^bB9HLB%8DR4#`eG){ zce7&aSW^ifG1jF);lH7uEM(GU8C^S8!ms%+R;=TMKdP^__6CfV=RyYHLUz}mpB|p_ z=42T!xYbF>m`QgQ-R3H$kS=?a;gqLS1x0ur_9Gbu*pRSBNa{Z}HnD>)PcpewM7;hj z0OnBxP$@PpFBwTc3TsrZPYfEkw8k9fBMQDB=Ac~ALT@j#_=j`e_5)VA2L?+f8(6cfLG7YMsCd*3Pa}c_2_viJ)dZSnR zsAL^0rIq;l>5&niEONdf47*WlZ*2dmA9*0;F8ic1Bgq#x7`!r}{y4+dF?(+=4$ndn z-~peo3$;HjsIf8k`zP_KUE0ujIWIhPcS#;XaUswtu?Fec^libgHRXzRsfl#WXQSQ&EUDQFfdHr>i$t^V{Z zk?qLVm!rrXtDN^>*G1xq6u;)5&m|rZn~!{C{~7*rgCWWFDbUDv9lW%8;k=L1D)1a( z=GEWN>viz2)|*!AS5ah!JuYB=e#7J`z2ttY%q4~F9$C@WEHyjRWfD$9$kg?i0AK4^ zJ;*O&Bye^5qN%t#07v4#kRDx46MJ zo$f$NK?wxWlAx9_c0$$Y@L!k$rR%WtrAd0AWAA4w|NE~Q+Q=*wg_lmZqG8>&KYPub z!jX)Lm619dL-?1a!@~DCmzuU*DRWI!j%k*=>e%2CW1KU0F)80RNvr>L$m`c2!%^>* zJbWxm>B{?Xhow-}5O=aJsJ0q_nSvPWj`@K%4L2GXY}?8?q{)9Z9yT2#&0+i@Rb#9+ za>Wro*Y@I#EcAt`?+{j4QBbB4uWAc%hXB$Hnbp4uj<|I46|u(mxv=i26x{ga3Nr}Y zZ@q%%!ox`SygFevg9;hASYbpWiYr}mI*LRkj@^}xazvvqf6=G&!}~{FbMl+^3~P99 zNVd8ieZ{!mzown}O0WxL^&R5u1@&$oyI_N@KH~^`)BnrJq17&&IrkI>QNr{T8h_;t zJ0YS1(CYc&_Q#)%FNw(>52aq0J2om&JHA2PM5x$F)Zm(hIT&^|Et)&@|KUK^#raZc zEs?)FuhQsNGz;fMlVu*Oa$FCQ@MaqZTJEGl2`&MR%TvExTF z$mlz~_}C`kNU;#DlW5y5LdLLI43CT8AC;3u!US7`IP zdcOZ)emJ2h8AIp)!r3ZbMA>){8@eBf_2tI=6Dt+p_iW9+?M47`Z($9mB1mbi+Rvs0 zeP|hIy+cbm>#4P5C>P^5TRg^U-^A`yfUmd=`u)q%Yt&Yoa(5QN%S ze^J^l>!SfF5gL310MNeq_mtr~_>TAL8?L`B&tToHN&FDJ$rR?G2$wF=bLtKAR4-}2 zU_%A~;_$!S%CYIsn|BGkyi(xD@ao`(%Bkq{p69x^t_ls1hY>^2fkA#Vw#wU!%cm`o z2p*11XRc1{!yOumQX*#nieX=r?3!vkoES_1JqvU%c@<a$WES0E$B&`!HXJgAk5O8l#R1)Zm~E3 zS$a(S!OyWS@sTWEn{|{%pYQ&0?X&(rMfByDHJ13UjgV{kmq70E#ma!O+m3AW6qq1=Y2!=d$a)imSRVH9;H0znNE4?bBRUjqQL4U12e|%y zJt2yLx~7V$Awq78iPh~JkeS(y5_G`MCGCx07Uh2O=BpH)DC0JBVf*_@e(mscAqelH z?=nyH{-gcBTJ&71`aAvW2YP8Y;b0t$i^EY#arwT;VM`*jy?UrnQ<1pEm_pGU zM%=^2Y_1w;5X;?j!45O4ksK^5U`IgsZ+W{jqy&DcJBDzJVh= zImr|=FC>J6zH!|B-NOzK z_k?cEZ_y~BGa)Oghd;xg(nFGjr9%~})mx1UH~Q5r-&@Unnb5eyUDEaQS%d#gS~LmT zXGZb(ow=%Ye?Ptg#4F8E1kY}a<2An6n)zmoMQLT4nI9Fi_Li6zO0?}XGvfTBM50<8 zZ-p^(J~QYHtLo?N*LYv^@gMS&Ux+(M6TS7~?U4MSakVt7+Bh@FTg-C{-JC?!7`bRo zwara4%kg?^#m+zE+fiqiqWzo4NzM1J6!N3_4Bo2$9!cvuK&?8_JIog%->yCEGz1A4 z+8VCictI#Q!U{y2Yu(-}ru>2@Lt;2P>>JAVfj;z;V7sIaOO z$-!xX;RA?CJ$U?r!j!+b-lT}P7Zv)xz<+LReUSze?M@LnpI8i;pcN6qbjC|UI4UHF zxaO})7=RPBHcbML@P#{5JH*^?^05*J`9jnhf(=s*4{1}yBj8I1J{=5(pufCFb05|1 zkPd#3Vg00$g|@zF4 zRv6c2kkKi-h2}V``Ilznv3Ryt`HqlH57tylY!_U_vyH5)Rv3W^J0{K!1f93fZcs(P z(Gp2J|4-zjoyc$uU=Tqo-nc<4OvES2{D$4ubyEBJ?zyRndz<^z5yV*r6BMyBu_OlG$oM_{-FNfai&|>|=?@URf03Nd+3#0aD`Z zHQay%)7)Y8vT<7vWEuNH7k#Ci+g&x_e{VuAim>4i+U zUVgf+N#kNpG)~*f{ssCB)To~gJ8ieNjxEd*;hoA}3BNzZsF24&^UY2h8qR)S&spL{ zPPQuL0xbJ$yjYLQ*Ccbo)=p0e>gq{bXB7=lG=Fcoes>h!%kLhrF8U`^dT)?^x<&S_ zK#_N+?a8ft3o5ldxm8`}kw?dTY8c;yRH>v&Q?5zI(A4&V37EtEmrFlHC+VBd)^WU7 zmJgfqd92uYjjdxY?@HrPrVnB8837vK87;?BM`>QNqt|I-Omf5T#4&Q`lTm(IF&^yj z?@JV8U9+JVw6d~N`0WIKXy*|Go_s#+*HSghVpy09KfqQbIe}l2j=APtaf_U_?1aQ( zk8%w-xKR*WkwOCn;{kd^e&xHJSTdjKGqjMf#-C>wklXj=Ifn!@^WB(`;ar|%ijZ+J zC;R`486(lsnhh;GH*8u{%vJ8H@OPjBpWQZR^)j1-LpzLpZ*p8KLuKf*s-&)inR*gp zlZ}~2j@?Kv>c5x(@EJFhEl8St@MyxvFM*~QKG>jPI(H=s*Hz3o%=>Us+wa8g`>Nac zI)+`K7Nz|P<~9!SvegBDGk#I4NTxNM`J<>dUUMSTl{XXh##ioC}>bhL4W$eqHu&%0RUP# zi5M&O+=dA0NIn0L4Pj{^w0oI~4i?Y7e4wyFd29Bn?^Any^f3-Q{avBo`A`--Ki{oe z@e{NKe*W16_-2PU^PrRAV)NI_N0*Co@IFTam9d)tBscICg$SpkD4T=^F*DKG11pb6_`e6TyWM^D5I+U{gjMw|wtR<;R~+evO?j_Vs6*|HQfy-N8yPbGCRI-|$q{-Qj8{#(PZ4!X z5sHz=20z!74>HUdV${wrl{sXxBySZqf)u*!E^hWEQ!k-GlOYwVzmO^FZL9MA$#(=@00#x^`SicrT@Ay-R^Z6fE&ofiJY z3BXp5_wp~bkKun=ykIrG1E=uTjY|bRPkChOiEuqsybth)!}3>XM9Ezi=uZJ1@CVSV zy$=yg!q%kYv9d4H6dpSQ)b3oG)m-U#ESvO2A`)B*i$kPR^Mp_eibs6tTV$I86CnPA zO?7m!;Y$Cw3~_;MgNjfB{NrLdJg9aLfxqD|j;HpGFcx0Wx%S}%I@l|;D#R^QJYm(F zZovA}Ns9K%d>>O;7QI>nue@(cr9fM+Z+E9SZa`M&QS+bNjvaALH>3K*`H$G1yjD=0 zb(c~;n@soHi6#%iDH^I7Q;Nae<7=GY3%fAt$m@M2*l?}C`E7PQhaxGGxRw{EhUi-U z8Gwj&G@$X1odQ&9DQ+H02EUvqnoO2_KRBIASQ=3)vz|dErNa7^trrZlVOi#J^0{fvppx!$ix6=3ao~YFXSxf(_XRc!zMMtJJoG;&jtD)*niXA`0wXQq#jiY zvW7Y%ebW_{bxIi3L=1=~f06bD{n?4M*KVnpE$rrBz0&^H8du=v?2XhONP^ zn6a&pUp`%+*Ts$Hp^KARVE0isOFOxRUBRGFgCJ(s5@LvGs zQ#6CEc?Fr*NZ%Vb>VtZJQGX%-1))*2!9L3T(FB;P2oQRpLT%KuTsx1`I7EK;hMZK2 zGgB~)`J>z2>SPzAm!fsE3$vy6qvDs#PL* zP7k$jsw=vxMc@iV&@yd5x(t_`=ekwjN)kvtiUu>uDYuPVJfkzH7 zN=PHAqQQ`arP|^x?BbNxILO-O#_ERkG7Jy7ak7#Jv!kobQY3`4q%U^zh?W|Ol>~x| z545aM9AYQe*_Pj&e0&PO_b7jDz)#i0Avngbto6zT)6;q_U%Nb>VkeWQo@wOkD?kZ1 zu;AgYHm*%^jw_}v823@pY>!y1o{3VW&rv@h6^q~hWJLp9qwhZLu4XeEbJ^SRs3^JV z=^H##AC>Rmev&l#mj0LSDM+Mq@SNEU{D`P^MEP<>aJF}&f2P-6>|yA7UGyufIa{X< zmy-?px++tO@zfX#w@{o!)HWkE@|*eokLTM6*Q)ADYc&CqY>2b=Fy>X)GfX7PC*|`& zFw=upDV~tL_uqpH&B$kr5lKl;zb=)=jZKkinw>lvwoXLG;#F2=SyGsgMfskr1^M2X z_;@lk<-c~E(Mnw{BQ$xhYO|M&out*jqERKj6o2fL>d(~T?&zEG`9GLgx(R7_zi(S1*&_O&_3HY^HS!TZonp#Hv7gka-A+*`*i7F`p4svKrYC4XvMjjiql$wzoy-r%vmp_UF+_1 z;4aac1fn-)yM(GMYPa(6rlbRL>-Cz}pqxH_++-^$nH>5KzmxPf^dzcB$qgbtBJFTD zhOTN>mrFfIgIR~PSoc41Ptk8%^V+TxFGY%Du;=c*@!zX@`~4|VnRJ^Gre0GklG_MI z&fxt_yyPjz%n~kPz|nx8C#CaqbefLu7Xy`}6zA_1vh<$YuncL{PJ%WhlasWofYeSY z#i=GV_#M8QC7kSU-XLTtjhP)kK_g^4MY zU@~bz+Ue4i zfub5pkVfIqoeO8SDddP`Cr`Fclb$P37vHQBF$&*eUj(j z4pMs8f`zYkgmCX6FRl{8yjtO1Ih=$v=X39zdRy&9&uYb^}h>&&Js!?&^b2d+fOyUnbiZVCJ-=`c#R<#gEwMEMF*9 z^5A)r#e&5t3}xgtu+GRCQ$7;u#oqrP04+e$zlg-MK=m64gN*$Hx|IeU3YS~55*U00 zOen+f2Stvp(3{0+Nco(5xU0Fvf1%Hc_@}Ef?UEllzz_GHE`3QIUYvBF@WTO0exy{v z#t6JLl*GdObv+NCmdRH-fb@XV!tm&{<-<}`WG+HN+AH`nZ{c~gT;a_!yd?zgtr}V@ z{@^#~Pz>&}g~W;0X>b{PqNKd*szR^;VZY7?2bEYqXYQWd@_$#nVSNwisw^$$L~pUX z3#hg+6qhQCthTemx=e{ushea#N<;0fMop8|ByQn+Puo%u`FNOVf2u{K^P(dor zIp3dBbKqGwzho)Z`?)o}s#Z=GS+cIvQ|xiKznVTOh5!Y^2gV_`C{EK%ARyr5Ki;n0 z1R!)5S+>SS@{h3{`uK|v6ph9aZODtnX?GVayv?NWeO2R*8`sfH^Yd+cx9IK9ZO4G5 zygquWe4=Lrw)m5|tGjwxEalM7#MbUa#{x##@yrv7LB>GO{6BGyyo>Xe6L99KYt0>l zOGW5+QGV;m`P+cdXqjb5-x668D;UffUsrsoa(zQ27Y=Ns}D z()6e7T*ps*9bS6o#5ZKLD0QfIMR%$ojAkJ%ctXW}e)>LwWjF z)R5;mz-!a3E%kI>%rX#C&=SEKHD;!Gzys>S0RoFohQBm45ot2pftibVATX zLV;a&DgsD0onbbeuIy+X!r??yqZA;6Xm#p;NVNH(fh+8gpOT4vxn4+jAK$78cx~+q zf%#Taai6u?kZ6uw{+b4E)342U4$po^fj9@|%%mfPn{8VSP|L<8@3^x*!@uY^e;)Q#kH4f{iYWt5Y zW@zD|2E!#I^QxnPuBMlTyXC{-CEqsvC)&3O4h{8?z#_ty(NBGB?6q*aFD3KL}R)7Vpb0n&m6i(w|ETZmIlaq zet4Nn-&?Y012E(T{R8}I-3o5u%OP_c#=%xIUiNhK@4k{MAU%M^WJsaqRXejo?y@e2*7w4 z;S4JvGnv7jk5U^9%zFoTb6oe{{vz$Au=`gO28&}2caq6sQcV7~Vv4Lkoy=Wxc@cI6 zSWHheV=R zt^$Qjexwc^z!wIk-`_<_{vO|eznoUpWit=p<>VXUC&Lg-1SiRnk3y>B8lmC-7NQa0 zaEodjNd+sOy^bPM>)XH=A**Dm=jm)4itCsM)E#{Hv|3-%j=HlL;~ygL=%d4`&kz~} z8_;G>JQ*RljYw32Qp2gJam9T(q&>UX@7A$)9rF(Pw%`E}*%KX5u)_Kn`NXC)8JGB< zJnlE1Lgng2SjpGrWuhb_d2=#ppJ@$HuqH1crQhd_8)na#4NcKQ zOz~I_zL6n5W7c9Q{|YpFM=6mZvU$S)Bz%Dz;qxc++&Oq0=M-|70^m+en| zt1M-I&Ei+x%xYQGbB|z&5tEW~4M7}IRm`uk+*nev}<>N25SxQS^|D(+VnOKb0C7uj}ci zt`;+p$=!;T0#OH3rPELQERcK?vVZFcFW0Bn{K|B-%{-U8H-f6D$f-J#+!*WiY;~QS zD6wi0ynq1*W906&NxFKb=M#lw3a?;`HSOZO{-8^BQs~5dvaku-s!i2KfXGwK1r0L;rHSuXR}A6DhjC!Gj&fE9nC?EztXV$2uDJ$fjZ_LR)KeVfiX4;_vN*>HL;q zX^|Q+smZXjeu7#-X(8~A`YD>!m3oEW&2jTR4i$8CYEVPfZ>SSpLbmK-y?o@xpj-23 z6#3WyLm%VBEz@{bFH9He4yAML2r9cVMVJYR@00nG`Nx_fP4{E~3jmpd000)t#_I!K zxlr~0b+%vXUKZ&!1Bzeij*Nezw&BV1EP-=ppRNy*kj|K667k0|%pIj)DyD!W2C4L# zaa$@{2gGwa%#q-qd}q=L=og`Tikp_Elp(5b7QM3F9;g_iVrb79Ks60$5Van_vCEb( zK-K5Ti70Ce(UH@a%7kbZP(Ab8=xzoI0t_@uik;}WPOR%t5h-a>8wg4ncoi8~;!yBv zG*txri`4(%1)mnN-&<;12rPOtlRbc_rR$FFTG_$d5Hl9hN0gXjcdyRz5cAfpfC1qM z>fEo2r}?QE0TJRBG=N;#Aft{No!{|}KlM|sMh#X@+uo}5|6TX;sehJVetX$3y3gq? z;%XTH3SHeEPPRWRp$Q`?yh|>^g;g>wvEnZX;g}m;@+z!4*+WuZ@O7GYztykn)IYjI zrEdu0ou2SxIIixE5FNv{)rd#~Ls5xnt~|oP&4@9M(q;d=RsNrq#qAkucz3Bz>d#L+ zdTsOJMS1YIAV68Y&!PV5mXXJ+48;8i1VD9Koi?zG1$~5Ffz>*f-kL+ZsuZkFF!iSZ z_SuDXWt%eeS<}enF@JzV3JR}PLVR5i3xo<2L5a%}}EH`)Df*hDv`AtnD z+tl1VzOy4j2q3`(0}hwIpI)*7$VD3rin6{u>Gu}pbfL01}l4jW+;39;xF z%MaBb)3UyPNnw;Q2=VtC-n-q(x0_@CX}#S%h0@0!<4kU*lRwmbg{}6br(gig2LvJX z2_*mlknb?#_<=!!vk1dl8g+GQG!FK|VS$Y+P+CajttDPKc)X`=)d-Q4QmCwWS_n8{ z@Tyyr3%VNXE$^VWs`U)VSP&)W>J{|{Wa-%~>brmHO4z5s4#gACME`1y$jDuwhc^ZR zK>#n8_jq=t_5OzUR*UcBBm;fNowENL1t8yHu~Yi;U)IEO3>PHQ@;=_Kv#i(fjZ3uS zE6+P47M|+5JdZmn$05UN8@xw$F)jAXYK$F8h)7A;Oamk^`U+JVO5|kDGqBDlIX`xv zL+CK1ebp!7-{LlUBIQCAGzJrsi>|C*1$D%`rbe_b?Q>GT`3pcro4+e*hFbmcLsS3- zapa;sq^jgp0O~dMn*IHPJr$$y=Ez>hQyY(lx?;t1&0~c+Lx@u342CzRi?CP8r|^Eb zpQd5z?G%BMwaG+5H zed4C2&D@I24(nD^$}o8$E?iV92s9;LrtL7mYS}YT3|D-~&7sdcf6m1z3in82PTQ6; zsWq1_lZ_C3AU=mWLqy|QmE$JtkMvT}Nc)X|$LmER&3MQDS)M43f*c~TZ!LMR*8m>3 zd(}-m%a{E8QOlmq_e!h5`kq}tPoWQlwm5&sVk(_s=eX04F~_bYchmYUo(DOUTsPCR zY;}f0m&XXJm`El|-O7A+fMLa{l%-|vZx-!06Y~!@NF5Q<3x7ju+qpel8?TO$$vB{) z6%42ROSY0E&~<-o6pdUREq}yW2A!w6N(X*ZMYSBF%Iz6{4xfYaSz1JMIwP`kymKDR zlZjALqSv3`*@%9nbzAXj`El;v^vFU)ospIJQpM=DkAR>1g^Q%R>CG`%*=B5Z*DbJ( z^Oin=RgFdoZ>x-5Kjjw2&II_Tw2cfk%x@72z0Na1x!Jjq5&0`Vy-vR(hfBbFw|7qm zcRdc<9}BZs^sUl3I)XZC-YUVupTS*_wy!z+l?%icFdAmQw|;5f^?XxAvO#nKUqGdC z>d4c#!zz~m-co-;J_U~}ydvCX`9+f)lpL#saDTyL^zH))rlPZT!&&?BuaXPP{e`1Wr?OJ>JZQUB1n!>*~vx?rfZ*HMfzzpov?wrCX9ii>2!z z-Y6z0B2q7hTVatfXukH9;SO3TTRINgIOnUo-pi)3x-`rCwhdNUWrE~pK-XOXaxw}7 z{(^|sod;+3xT@`XT%LNPPT{*i5b67MGQ6b@RAbIPBN=O+ttz!0*3l`fAy~7qb`VRk zSS0|+&|m}#@JS!hkYo9&iIL(#nDh|St8k^;T`ZT2JJJn-%i?8-9_+R6i}?T+I_C8j zos&@4s&>+hc|AyF44*4x?FRNj%;%xFtKv=yBm#oG{%^8}1S$|NgU2yCg@I7Z2gH2$}Q*u7DEyDT9IYS(GBewvd!MlAQAWW`7W^))$V7PwM-Xu!V|P$cD>7o1Ha zg`J%m1hH_=+9N3=A8wUTbU&<^e&-AGMKK&olEVc>%Tryihc&V>r*8sZJYlMk{pnr;=aK1B3K>)M6sm< zoyjczZFyQrHw_+lJ`AipXPb`a*F~{&3^)e7&&=xH&8+GFQ(JE0i@sr~<#??XBIfc5 zAe(BUW0%r5essk$G3hLEHq270twytbM&ciB+BW7(rzZX?F$=7y1E*elor)1-sWhHm znmKhVvR9xl2_Md_QKQbQ`2mvlZNeMO~FIZC1G#Ulq9_c-*Z%YCNXBB=Xo> zoF*yuvhZsN?@hB`Q6{H6Ve+BX%6h%{-kt6#o_0;`0WMz#JPe+TyKbuQ=*P*>kqRc& zDmqc<k?H)D<99!Cu(0ET}ydTvh8*zgNb z$5j@o0cJ=80-|$Zl4!@#l<3lnw4J0x_No*kIVu(wtILW23u!v0Rq+clPnb1Cd&8vl zfC77ipFKhx-07OL$=9u#rjNa)_c}WNJQ=W#IB1@<+Z6b(wxLG`J3jU zo%_OmxF6FhxT97T>i+wjggI2i^smJpVLUde{Y>J%CzdnE{fUqC;y;P{ch}|iNXkP= zz>LO~39-f^X4Pgwzklv-aDtNn7fe^46P%@FgjB=!Y|L;s+ym-U9*fahdvA#7!<0V0 zZE(C@kw`lR8(CqVo*B>!N&HiCd>q6g9ZC-N^A;zS?QkNtnuof|)Eb}mZxD~+0F@#wTy9T_ zU$qn6@}uc7A}Y?rT4})YBOb%!+$VpgtwzWp|8K1LbqO*aV|oro?($TBNmQ%^4n*3_ zhlG`+|EN|J9HaE;r~xw$Y(BB)WUmt+vqN&GgFQAeLrpNa>~M82CT#hxnkzAhu;$(* zLyPWJOkh08YSSixd-KA|-fl4NT>-k+j|Ra);e@l@Uv;iKetl^D%BD&RB1509tov)` zvU?qBi0d19O07nX7SNOD>y++U#j)hw%3Jp)aL4SC1DeuJmb2xSzFmTUS(KtT$-;&L z!4iu-I5gG;A(sZdnM-iAPpKl={m5CriG%Cp{SRk3_ll?RPAT8Et=zicHp~PX>$J9~ zm8Q-QDUNxQ(oyj+6wb{t{0@!>YoC}j>{ z;AjvJuswCMJU*rENW&a^dPycyZ9sqqH|c`dgo5;2z3<1;z^YsdHcp(dBCbEHb-QK2Oga!RZIShPOX^~H=Dl^Gs7 z76=CAZzNkNf1aQ$zUOGL;*|7-?)yeYHu1>CdDVMJX5{vC%2FMb5|otba%eb(t20#is^@r4q( zh717L)=rJGpL$e<$0$tUw;?O`OFL9#xkLj()hqpw{||W`@C?_731UUK$IGh?p@)Ly zI)6-r1WR%sc@dAAY|tBqhr3gxIkCp@VrN^OunJ#O#V`^vu3|WW_t5o;0#I-t86AVeS z5{pQ7e~pA!XG!>5IO%^(CF$)lpgcKk7L`g7{hTe-ux{Dxme;ORE+pf6S`62X_h4M6 z(laL*sZ?A}Pt0jCYeA_L^~}0QaY|J3R=3=)qA}5xKuEo(U2-}XG6*4aN6}!TO4T!o z!$HNQyj%cOu-GH92ce^Pg2jHjUJ1X=3g3D`)W9osnt0Rb&Y4DTWP*|QjjNfp3T3k2V7d6C`O!LQImNb)K7heR<=qx%9adcs4ffau#au6E(;e%^nK4M@v zJWUak06{?U?Mo3(lK1?wq0L^lt`&J-r05aciYt+Id!h0uL-Z-8^7s6?*c}QDrozo9 zhpC2(L7LN~N(wQjtldQ(Z4p3EUmt)9W_y2~!{Wa*S}i9Izw(F;S*>NFfFOtiaD^A8Wh>|y0fPnw|Hc)bVwcg*Rb`EQRyPwjFn~ky(3AZod4Ns2ZryYgmmdX7rE!9(n5#SiU0*hzKx#T?zc zNFCv}v&J*MT_9YY(|TxU6DbF z#8I}I&ni`>aN`SjW48Hk;>@Jb7WB7LhnK3L6RToX@fTtVQhG z7576?aacdKiaK36e4{NNKd|;iy#z)GfG`g`)AlGQ!nLK@x$!|?ZH$yP&5m+yG}TZg zDX0N+GaS%yCSQf%mI$~XmS-5k0u!(5*F57_E`zVUSq0nJx1`5@S_@Y2sa&=-THT8j zwJnTNOJ}ciuzmW=jV&C=U;yEE6K0h}q)YcV*(;=B$k#1Ccc(8g zqs^6U_H3%K&%+|@aJi>7d?oG%T&X0SLSeKB&!J;RVu+KfJK4H@ByZg@Q<%gz!lV!?owsMY@*yLZ# z{P(1176DlIG;d&1LUe(V*!3NTc>8i&hK!7(ij6#-l`0@bKtR5jCQcf0Vm=#`b|X?t z)jg!%azNVlP^|)!HpFhunCgX@Pm^EDjks&-HExCteh?Z$1qy;b?9y}yeMoWf15R}L zE&d0Q<6nb)sJP%UQ5z>dm&5xX0w($~Hks>mw0Kb3Ykk6b1i25}5t$ga~_-9Q0*ul7=ISlnyYsU)ayipFyBG z!P76ySz=6la_roI2qsBkCaT;j9P4L`F~?L!s*=pZ(#^$OQmxt+xX+ZytDjg?;zj)B z?9Pp-#~FwL%l`z7e%4LNOjIBoO6YyrKI8>MU?%@##Cm{!%_f3!#q2uII<5xL_g)DY z?hLrkMP26KGH1)fn#S*dlu`2%o#0ifZ6%=_8(KEr$LSVvsfMz3wtC7+Vdnm!43v)u zjYz>;JQo*N>+gOeD=k^RL(di7v_U`i{B26z339#X!G3Q`ShG%Wx9IQ_H0BOn=PW#| zXEpUTR!n!ICDO35x2cD~?;Y#?k<+ts6U+D@#y~tnCHvZPq>osE;yE*u1AOc`Tp9mg zeCXdz7mq{jSP{Kf2pK4ctltxzm(o3$) z0m?0SF844?C4IcaE^I+#EI7=P0F4hGK%LWdQ_7vOp0(`Nd#bA*X zoIN{2Fcxh_`u6tHO>l`s((HdoGS zuRTz}Am2IPWx^vXA`h314XenQeq$(o;VD89|1s6PcCJ60R;C3xxuBG>dcghaECzr; zB{;5Gch3Zq_ecO~G+M7giFJEfk3(-y)kD`v+jmtqEULajtLKx^oiVrVe#$ps;F3=c z)AUl2g%j=1{-+|aW~>)=ce$W_5p>4~0uZ+e4^A_TG>38=7d9{(`SnGOFUf0?$=V;G zONLg^{ozFv-MtK7fSl-+Y7!z}D37yaR_SgJwEu10>}8>d0Q2xPBvnJ$bsJ2r zSgt4z2D!;%(5sMql@i2 zVTkn;?jbWhG0zTtARptWh;rw~u6HX9c$CwP1`^d&&~aFQR&k+|&%cvIkW{h9Vizs% z(xcgN#h?AdZ89C{d6;R$VPu`9)ffHV_hbgM64`{$AYCgp-4zO}f6%A+wX;Vh!C2xb zr > z{*676jYr>I^=V-GG!89efzO%c-@udB?*hJb4^GMsL(pPS-+K*Z*=fHXP$ z7OxS%Y|@S{?RAD;+j&LqKy)qiVdJmu+Jk4GMEHdATJiJBHqg4piRnUK+jecT_~YGX z7=a%-#T0Iqg_t8kuo4ygtFrXk6tU+C0(YCLwKwI*m@4`E3VYj}&=vp*zueh0+J#Dr zbqz@$CJD*a^ZA{PJThiH1`kJ7d&o}^7@l()(N$Xx=BAh5=R9_5Q``>-Kve>XgkZky zj*-Tcq1@&L;m?aG$-^7Xec;t>(t6A#rx&Qa#iTszm-vwJei^TKIyxsgtr&#|R{!!g z`Jubl*S+*MTD#1!@?BX%^K)c_??uNNec}`$BxW zK|eWkf37+#((E6RAxsw^9B`eQws~Q?FN2Ee+5ByRfUZM=YSkNgb74uHtseH%)jsDZ zV5QdJ@?4Hqa24o3eyNn?IV`W~WMq!0lsKwmOLjqg)gy^p|A+i(L~pA4wyLV2031>2 ziYK?MW_0iD=lMW?ZP*4x1yUvdS;ydsVo@?TiZ=Eg)Fhg0M@0qE2 zwK~4?Hw`9glY8eBkJwl(G!;>-;g)sI<|3COYlw02uz%S;iof zvDh*&Fbvz{CDJ_ME{gI&QeJu-qd%AYNM?|dKi`ZvDT;}{G`2SHQ&fo?1C{&Ubk;%= zBXRsdZMD5AMPF;gM*X!qA<+Nzvt>}D{wVo!>hH5YoqG~Hn@xMWHwtc3b##jv(+bA~ zzRpKW&bi7tbwChk5`l(smzf##l@VOc=%-?{{{E;iS6NZW#ixJKw4oSdPhIEA{q{u~ zjVRpo>-niWDf%AsWv+( zzk%rvl1q8oBMyDqb0@}|=6YSwpMmD290ggDh4LOzHt?()Gnu7id5WYuk><`Wy}Xf> zB#^+*-KXc$<$`t=aYDkKz58bAzat~Eh(-`<*O{k{yNWId4Q&@D7~QO7x+lXI^&ldw zz^hlPErLLNF{282iJ5XzC4}q0wmbOHu8q6@FMg(1t_Cn4P^75*Ih-eM9!sr&`((e7 zGid z#15qWOxX8~C>JTKqn|$RN6!n(RROGj8j=MX!gnTVeAt^HZ%hM$)tYELXD_Z0Y&%+F za?9?%2xR*63Zz*1fw|kqMB9wNVWn)%wOlQ)l)YWmQbZ7pWtc5lUs?6UZp0Kqn}(H5 zX;;F0GwApJIqDbyr5IA}-z_RywMj@c;R?H*aQ9sfp!!mDawtn8hqd0M^M~qv;Eh_~ zoh`X6^ZATGD$h{+u8od1i?`tO0x@QGbfoyoH(d$@&{&+9)t*p$+wf zcV`Mh3`y$&5rVCB?Fi@^(Y&OY6_z9J9ULg6b6?%mDg*8B#qUu-DrC|0*3OOXZ9AR@ z$v{xsWBo3xt+xy@9%Qj(&_Qj-XOEZMR%Yhl_Z6q0_##^IN9TDjCD<)&R(9V%4t`p4 zk}sWdPlKEGJyryqu`D0h)BJkq-6&na_yJW(M>e$QkYL9ITeYrzL?vd>_HwgKR4j0O z?7lwly>VO0!7G)Q(i$cues-K zp~6(A#2_Bwyf#(J}dvR7&Wv@-#Ii z6wNrfl&Vbo3<{SlEZ$Cb)%yykuu%Z)XjC>B4C5AT?U`+mxtQ=^_mT3rjsC9pbmrTB z_V|Y|hIXCVzghjyeZA{J+05(xLA2%(>XYC@Fs$`avawa<5%TM60SIg${2MUrJRUmZ zQj=z0WRCut>gry5u<)~Pu?|*>yAUSLJwGhH-TP7MIb9mhY8$AxLYV{F((3o8{^k!&p-dv9zBA~juA7I_K zClmQ89;N|*_j6r0z_R$rVxlp779!CeP6 zBF4GZM=Gi_xN7D%8~bj(BWo?wPfXybFR24d`7cg>{IbBE3@Cd2W7PNKZaPj~vM$~0 z2t8*?9i$4TM|d96w62DN3Fu^?1yzl}co)8zZ4uE8!mEHKt}RKs=s$AqcIJ37rlr!s zj4*})f{6y9^}jT}`cyccY9an=CK>ZHn}zToPM^(zl;t05>oZ^Lnqexxl%(rmUk2XT zxQ>)#?2%5UC8Ez2zyNf+s@C5O=S~R{`ir`G;Z3k*lfmqi0hQ$!%)=Gwul1UcEH8*( z*Yqu=i;2|SzaxPlF?Y?DDym1g<1Lu7Ny9}0%f>h%rf~t*0`FELU!ZNAN9V{nKPimgLv>W{!tz<~h<;B1F0tF4XtwqXvzIe_Kl$nNErWlk) zl(mlC#(Z+*F+4uMptRpL#9uLVG#OV&qVL;w!KC9jYR40+?t*qpcW9nv6?DfD0pA%U z|K@k?`z?48+%;Wy=i8h!)ZnL@VSn6N$*<*%R=`#fNrvRgn#jK^I0BU$I6cv~115xN~+H>)!r@>YKPeq-49VR6{g z=)UhwMH8Gi#v&E(Pl6gg-88 z{oSM<6_-Z1ayt);GxnG2(dH-ZStd7uzhXiZ2*vPx_+w*A)K<^)B2abr)}~+CQfwOg zUklc2tEA{ZfnQ<8={MupyP$BzJJLh>Uuz9eGB^U|}F7%!f~3*Fq&d zjoNkt{#j%@ht#yj<3}RHoH3^nS-tJm{B%ME+{k@o@8_c#(-Eo!n!=vjpZeI#`5=8( zB~iV?lx9qF>b#LZf%!X_y@4A zvfXAA`7!B=R#=|=eah_pd2o?yjPz%D@US=RJj8C3>=TW8ZfHBwTxJ%CKY%?MfGnQ0 zaUc_6XYOy>7*7Wy)L;PeXt0y})5=%bYvrHI~meIy855?}QkzClf{qOq<68z(z9p?{?^g}(zT#xS+oCd{&3+{!n9%A?Zx{zdf0`#e(( z9ujw$4{GLf8L;?5d1}hzlvazpTIPAsfR@^HP5Zr&C8K&j zFwaOrj`bp{pV^dlly6q%Zc)-T3(^`^vQ%LR5Wedg<*&nDM~FOb=@V z3w2b(7z@O;%v_%xvV&FovfI(Yqhoj}#?f z825_K{^rD;{<7K!g*9|Q<^QhmyS*hZVKEcuLx+lH_c}y{nOnB- zP|{Xc>5QlEe!~}sa8b4Z@_6|7gY9u=q|~`;cqOAYT^nwOv}E!O%5|&Ct2B0qC;iE; zAt`UP`4l&Q*6MYWi7b4p#U22wA~fAxBM> zcE3werWQft3KEA~-`ad<)VQND!0=Fe=K5-LJ%hXnz_?>HKMr2Jl;!UAmg$xZxO#ay z9(&ULTjk6sFwqht>nGi7TL6F($ASfCM^j*`qsy>uF&80j$;b_pkoq%9+GgfzafFWry#o8KsU{f+#zJZ92@l1p_6NR(*CKH^&{6Is0A(PVrR z?n7G|7+}2f#Us+yzc@^=K_A33AvZI0Se2SDE83ZY)-TV$8%#)cya=>-FKx+Cis@-u zAhwU1zJlhU{I-jvmdp{Vd3}&H9y)mm)hVw|$n^r^Yvy5d*P=-n&SqFBq+0!9_ufg+ z@r!_;0~f=d&TyS3%mkn1H%pBYOY->+$$B1I89L>V-}CW#lUy||7P5BI8z1nNoX2Ub zFg>c*;Er^gNMK>nlbJ#x{k)Ah`ArFZe~A5ZP}rP?P@CjkEtp-H4-C*Z0NXC1OV&e@{WA?B0WQh0iezS}PBo4TmX}nD+$j)R>+wBVpFJLp ze>0bZI*#8DH8zOG^o!ze(UP5f+pe=ShcF^~&%4sNUcHaN7!DL?w{(_~z~qKuf_$&n z;qjeC1Z%Qsj}#Zxd_$RK?6oSwGiAvh|2<<>fL|D6@InzqZ1zm#|h%%hmQcOqU#Z$~{q7 zP!euk>Rwt`PuhJbqP*3G{=>f7g3o^uvVA4OrdDh^+LjkuM$OnIATzx_ou!i+R0Td+>Jqzk6dRRe%Hma6u6R1V9lF*aQd_w8`HIl^zzf zbl6~Sma11K>rn5Hynpx@mkq+D)#t%I z-Wj2(gC0rd-F|fxJd}CW4kDc41`;XWv!LnF5s*zuiSo@WFiNeR5VC;^go&aGA%cV@o2VPf&-zlHcaiTRdRJ3JKHN5PjmJg|#kH0uzl2403_Le?GuG)E3EQqi4o9(=d@zRm|B zc;(ZWKRaXSkJtC0MClP+5FZyRgzE?| zzy@Yum>P|el~n}vqektj&Y_tE^POHnFe5WF00S#6t^}(sdeCiX?(qR8Z|jm?3FTxZ z0p;m};Fb%nVAoKA5{rWbNp^6q@FfUX28z2Rg1|EI5p7JtnGS$1Y^|Twd2r4sI+IZX z8wV?i=ZKin1WKf$S0M5U`5gtK-5LO?0&f%+YZMfIVz?$5VB~==p!U2oV(=A-GIcLi z#otVudU+NW5ieRVv-+|is)lTzND(OL^nwIonI>F;6Y8MUH;AzkA7NieK$^w~iZq&n zWEzuTO0**<@@Wn5V(AJYo=6k3-vt_IxAy=5=p7xOq5(H0jblN(Q5&qY(WHCx&g|QU zVP=3cSq7p5N1t2yD%71_~Z#z8`m5at6@0D+t+d(^dBOkMYfo@nWzuxB#%*N$ABMBhW&3rw)c*S$IcQ=#>ykt!u!T_ThesJ4s_zW&wzU^!Y!2S`J@GXBcPRrVU$Cz-i?2KAsGi6n$IErv$YL?=mj)iG_i}I1zz= z*Q}Ti4~a%Gg}@mpAq8LyLd%wbye&(&E4n)`{7a)=8FFm@K?r{{(py6bsXn)0yO^Tp zhYF&lv9__Aw-((r;y%fACg^bK++71!o*t+TP}FXqg0(|?Q~g|`hie>xkH1-?I{^^4 zu`PrG^m^qx)c_>fl>|D)mw5mF8WR@cM@At=?_@hJs{nm0?m*;FK*%=Mxcn%<Rj_wY@PJ-{t%Yv_{13qgtTPCA)?fs-D)<6G3^!*NuZynS%%63s@O$ z6`rj;5Y-lC;;wl=9`3KW$HYa!4b^e4#?x!mp!|lK5e?g9=;c7hrc&1Ei*bMe3niiL znzEigljE^UE;vUu@#@-_XC9M|Z7Vhyn(+SC-C2M17}Jp#Fl^0AAAk=t*^6{G4Eu{= zQVkD;6q#k>w16{)!(h6((;p=>Yh?)v*EKwRu#b+pSYXwfSVBDp0}=1CEst5`#m(_f zg(f6VZ=>JvSdh0VdV<{ZJtm;AW2mG}?K1!bWcqu*PRyEy6@tt4%tpu=!!y<;T9S=~P;taPqYS0t-<_fG|#+QrOnZHa}mR!!RgVFKA|ZQlN3heGku zKGlb>Ncov~w%1(udc`=tUYha|cev@+Bc*wI@jOf>0>;8?flarAYeIkZJ4&1#jZhY3J^*E!nu7C_PtWN|P*fD9Vy4^Fi4lm3c1cFv z%Y8*Y0r|Z$Ssp1c-u@!pzqdXrxnwqei$gwtiIed;Q%<5)s*PuB?HgHkyCva78#OrQs+A=s0N$jlw6 zf?k~>pv`Mi?;3vH?JVHvg~1?%BivEz&U%4Z_Q>_EU8+X&NvA915q^ZB-M{ni)vb}M zG&yi0#XUPcE6iP%*qM1L3v zUBU>3u*bU&{*VTk&ikDiwE(i1iQjE@e_QwV<%bh4rXvrj=_!usX&Ya3Z=*h9&tYO7 zZuEZgckjFh7h~d6C3)QiesD4W>Ki{I(^?r6t}Unm(VR-BbF3PPJczgK6XBS{Jl%Wj7yQ{VNmo6c-pOTa90jNuqUVSwVLkRzB`qs_YH- z1dyZWL3P4aL7BS5D50E-MkqqTK!R?IoJ(S6$}IrF$e{)UQ!r%)k_kxS^pFz}(ICyg zG|(%+*cwfVk`KgS1}01pfPCZzZ4`YD%BqwE8z+TQLIA(nG?Ip}KtLoJhdwWAjSRpu zF=(^X#Mh|Rp}O#|Jm&kPI|Bw_T+7Jf{~W3*&X?wlmKQU1bagP54axFzkAtUwMSs79 zJw@3`^GaMDwjjiX_}WqP^v6Jq2Ub|5vvl8l?{KuW*xVFaoVZ2IlC8h3C{$e_WFIe( zWcX!880QIO^(iKp&h)0f>9lq6awy-MOE1m;=;U~>>|6}xLD&wB-W?(UU26EnE$#JZ zcF&@nJh!F=jt0lAz^KSwPTgE;tds=ps4sTmy6>UCP2;L2#Av; z5HN#4Bp6DDl#$aFBqWd!XhERuDMCz!q5>_e0hBv(7cbW%mt$Z~KJ&!cnzZ zoqK!>-y<6aG%^wi6jvEZ$vBo|c7gT_Pv0riCk|ozGT_jXM}(KjeKQ`aWE}{U*EF#zr*nU2XQEwVsD2)< zCmbuF#X@)aaL+hdnl1;`Beu>CcbR9-mdZ>>gnnz?^jD$RQ{Ih!+4y0w83-9#L^52VH;V}`N-PeTiAe4g#tz_ae`8RiXr51R_&9U?v4X>|(u z$3yM&6LuGl|F&h~t1>8ij$)%-filpM=K+9x6Pf(K!;=g2_l9Q6w`DY^=5|yABBNb1 zy7ZdZ3|au_<>J#huK`STeL%&MO08_|+jiYT7&CV*{>6$9$}hylOYT9nGFCZ3Oh~du z8tiP?@fg@Sh~o`H7(F$On&rmXs#eS3n@9qFOlCT)k3XHbm}d&e16^V|PQEj^Hxk{;CSp^8UL?Y=|y zE}u_@_U<|M6&j0cpjDoz&-I{#!^&`3ZOH#cYN1FRKBM0GPDn6jMqsKsO?Aurd`)Lph`9QG@PC>s8MOkh z%Cow1_t%c%Qr|psXCGfg4yT{GcB8tYaZXVw^??RrSqACz$`TM(O?N z!=cbmGyR-L5=I7JSU8rB;WlBa(v|PW{ysjb;Q{tcWz&^851^!bpC*_l4F~`mJyv6h zzfc6EgE2p;JvJ~{z>CHN=cTdH8%h&87uDz|wC+WF#e!oA8}k%`EHpM2nhNT7(sAXU zGuysn5zOWTA_MC!qZm$x+%&%3$WP zBN0T&zwa&$G8}u%worN<{cX_|6st5wqn*0NHRM4o)I8ZUkS1_Toc#6&x?{W(WV;r# zLdGBAnaKx2ggrr%lU7L|Z1=Fr7>q%7?)w(r}s;<9x=Td$#sqTs(A8tn3!s%nh~t<*~c z-e%jD@%%@)``k9OkbQ3xrc#Gxh^4Rkd11O^Vl=I}PSE)(QxYc{(VZ>TH`b~qAN+4s z>U3P2>#~nIqjKV|5dT<0hf%5`0mJG;abtRxQR(dq8*>kcLFv)SHf+(LG}84>)&(|E zsjmwd{x$55fmA9?3oia`YfrCG!J&-Z;%=MU&TPx@TLZ-%XE+;p#B0{)tV1j7XLkHa z5}lVpQOq4MB?%S7C?%KrQoP^Q6UrSok9qCe8GU_Tpy~>Vq`c_U(_lFw@`UpQ3Tywo z7Ulb|Q_i8pptd%URsrBudU`r|6U=_h48Gq2%IrV2(e3tRd7bVnncW^|13iGSuF`(5 z?nDW=-|Z;(Uml`&WiE$XhAP;gh)NECz;(3XC0YOL z_CbLRV5hgQ-lczEbpGxT9_n_#X2Vat|1j69;w{TP9PMm;5w-9}et7NOI_qEz*2li}+W4H2r5-5Bv*|pY~-e z;U*wf8Bx02zdEFJb^o_`4$$IAhyZ}4B9MbTN=4r4$f$e2J8oHC#n#{UzuF_}FSdJ}a4~$++wBIcTJI@??TFxz_xKWFz$6JGLpDNOQirGZ8?;Bn zbig+hHMs4)3+19QBse3jf1%>1l+iwqt7#RQr=EjC5Gg_gcm8uarR;qm0x*+jkQbhb zCk~5I+`(&j!B|U=XBM^wVMFnWV3Pw{FWN;&G0Rp9UGBky&N1`G z!K~ss^l=O)c>a>W9#~N)J}Wqrsa+ljTZ%$61Ah?zVPWmOgW0Gt6)!bQ?su{SCsapc zW(R;@VIZV+H&N`Kvf=orPJWgUL8tO8OM2bcPo1R_Jg4FGzmIpv>(>J>z4{@cV>w^P zj@RT>*#SoQbN6D2vl)t!Tm}=a36nq3^U3iM6@H5!;JIflBG+wy-8L(nMEvuq|^^{zk_~OkiNc!82+};LJ%kjR;r=*v9udE9Mkbh-+ z@DAl0IM}6jzXhk!gsEQX3O;iX2#YnOrvIu4XgzB^KW=mJx~JT064VWW3u&Xtfaq_j zH0TQL&pD2u5-U=`&KRs?McFC+S-WC?IunU6Z?9BcNkmWb?o<77Gs3Bpg)&;#wQ#jW z@%Vri>Jgdlpj+4+7+pKmtk&}SbH*5g1#OtkA`PnRg`vovYazWVf%>00!|i+!ovBS; zA`e%sqKScOoU1NsYo(X9RyeMj$qxpe~)(OIytvE)67&HnSm+B&cX z2l)=Cmoz@R1^_&s6DR$1zX}_-@v?qWPW5TZpnwf$vJKn88Rzs=G7B0F{8;2d@N7Mn z+8B#T7$09>jG{^Z6V%S`(3puTlRYC3+kd9)o93Vm{j)n-aBOWvz{GyNeB+2$B27Jn zSj-IX*4@TDp9VSaGm&%sGyKjv$}qG_2uNn`mAM=*pSg(d z>fppFspUfo4Jpa%35*(j%B>=ra}w+>5a~Ny3UIMg&sHBxrjdbj={r$I3a$*wlx*4s zdTsh4FJaZX^|JlQhm&t=pD*k3!}dVFI9PeOE9^|GYOw?3J}$Bu1*f7#RZCa&Zh^ME z17go58L&_HDrQ0l_YkA>-*3?XVB>_dh&WP9P(u?Z6U@UNr2Us8{i5)e$;GwT6hDKW zoW#L($un>I@81Wn2Qv#%>)=1Y&YHC!)Dq!ggd?(?{wtzHfq7ezAlxB{F$iNFM`-E$+fB3=_sSJf&cP;lw^@Anmm#04$KV zJsrhX!VlvxUU~s1Ni6_L0eybGs^HNdi&s&s{M71J-PbqprLpr&`nvNlnV$X{?ao%1 zwE-rvV0crZz&GI##drzZD9BkW5K)E3ux__^+!A(MrDw*9@YU>A9Z;%9*X$edJws72 zy!x5USrEeq$szR21Asa3Kn#OBBD|9xZ%*B{WhaJ6bs4I8zj@zs%3|Qnx;9&+2@E8G7%>FNMh| zYD-h6W=z8Y^phXIO9giI=^1h>Et|=DLcA&9fd=cDq<;(+jSrm7Ez_cU z!DUq#bP#U;Bd?~eK(KU?i04-f|xW!E^nd?t0 zo&Qnvf07u2?|qDucVUK0m>V%=PLe0v97|jLOONFUt7j2bg2D~tyQ{Q8<^M`ePjvNG zT+o7S;tA%-=*nTjC!?!)*xjPJotdzX;xN!ShuYAkm>J8@JV{6EbHZ_GY}^;+c+l4Nk>B<%uEV5V#}h!zNbm|E=W9$TgR(vhRnX?^Ti||UvB!ph29GpuxdMw(3quhf zbbqvaXy}pFX+qbNp;*PryLJ=F9M*QdugkT!Vn}EP-p?Vs{#5#^DzZ&Sym@}{}rPDl~eA138vwWDf?*C75^ zR$IhUluLDFAXv!!Q|(h*J?fa`avFD1uuD;#9~y?H0!f0O(d$DuSPQ?$kqG3|mNqM# zZ;3Y^eMd4O*$n`poEEtSTdm^TZH1&ku}exNk$nVfP<0;Vzn`|Vk?3kzyl`NN6;xV= zifiwZZA<Uh5kYmoJ1J9lyCprs zdmZ=NoRmISz2ey!VV`|zyX5|zJqK-BmV)-ZGbJH^gwy^#4HVmCq1X@Z)I=aJ12Vd#@uke)O|np zf7kVfh63}F%)+e=6j!(rAt2EqCW_DX-_#7=MnC=Z?xVKdfsN^Tpk!=)eWV}Orork$ zm~a!$w3tQN=ixkCT|a>)pJS zg`)zkd9LM#{;WuSRY52I#Iq}}#6htW*MQvFkIeo52?j*Z-*qDzxg`jtOCO387A5h@ zt5`t3cx5642qair6s%UkI3mlyAS%ytD0(xI6);OqAjQ&?!Cpau#_wY<(+lSrK>H52 zmmgKAP;hOT?}$~SLV_+Dg@wrF?Ed@(VJt|klxM1|Wi*-|>+vd!8Qcl-u$Ow>kPG@= zRs(uc%c5%~2mSIKdrO~YMyE2%^}fiM+NmSauS@@nhqgbc_TDpboYZ;Eawx9%;h2rk zue?)5<&CD80M>K^?Nyiblgg5%l#Iy7v6_l*py{Iw15%=+-Bk)cs+%=LAF_w4xnJdr zt2x3)@gT>EL!e~uTy?L#c+iN>j0839&df2%lKeBC$4na$%VF&95V03)$iyrt7`g*2 z7vT1>8LovZc3UBqUHHNUyK~0H#s)o_z39-s7)8KcyA8LCY##1Fs7MKm15SV!N(V*K z+yF6h{&|>lyIK~*Xy%))-^KDD{_4)l0VjjT7b;Ks=pQA=S9-{D+>NIzJ2o1nI*7! zI`^7BDf0tbeS2yN??bKc->)u`KNgH%bi0=UYqRmRUdKpBUDQ<>Nt2#Ig>T?fe^AAg zg@6b9Dpg&AK2hdvN&RwJu}G(%||B%K$VUU&1ZrNNoLBsc^Ico#$MgHr0(@0`oj!bR|ePXVjr3W99jz+Uf6>#UUa7g;an3xM zZvUzIN3=WL3Z6z_DGG(lz;_CEo83j(w5vUca7sGaR@Y-O>-{}-c(e_}yk%yW>&xD& zF$`YuX|0#aR!>3>__Q{-cn>&DxFLhQyB%Y*%!pf; zLc<1%B7N|>D?2qVI~qvRtxQ@;?8&J3b`a@3J)1Db($k}7?w)%t6K&S2PG>Z42bkxo zF_?@V)Vhr)pFMz+r)ZGOgys>|v9DZnB}$bm9*+mL==((}66qsk)s(G8z}rRUtZd@I ze(+fI74NZzs_SAlMnAl|(U+1?@al5LsgAs)hxtFzfX7N6GH@udeq+=m!sriCc%+Pe zotzARL|RP*yydI<5x;gSO+PT&VrRDW!NuUgwV`D zETI~n=xM;=vxByyiLJDIbg8c)7eC#6Yfx0w*asP8dvNOxiC-+QsF|}?R4ARr0lZtD z8ocxphW2mS|MiFcBE!A|1xrq^jEsMtu+HA(VA|h%%dzc_UNL3mdrf8yf)k#B9I*q5 zzXB!%!)LI;x~uyVenjM>+?GJXU}03Xsvtu*_XY>cUH5+GTT-u`?9DG4WCdowm(|Q< zxNx4l&Ngamoj>;d=2AuvyR7G>^n0e1(wjZ>8&=tsUIrm*c($3o(RnM?|6B_@ zU!$L(F|m*hRKB>Mes zVy5(Da~}(arh=`0cK2+*m4oc6V{t%WOz0!u9geH`PiP;vXjv+q1Y$h@T@*vxI_2l4 zoR}_wQKVP?a=d5RV~)*2y-xii<}#U8G@m~T{1#H1@ph~ zo~^4p<3Yob+ol9u5<=g;H!nHk>p^%&5u!H=Aw42e2P#-1dq?t*Bry1Ol37gQb26?h z)wr9toebS%GNj$`2uqe=)UJUBdhrx&nEN*Ai!)zsYfot6|9b=;4^k|HaarBE?_461 zg}{O1;3}_)5$#79QYG0nnHK_5L*Geazupeqh^`BQcv`W#?Z|#j1)?s;fjr-}q|f7J z6~6@8`_AcbS5yZl@9Loy^>p<+<%6KnA9%FOsm$PV`MJ?`z2<(WU|nlC_N=>A-WmAc zh3T$UoT1MVC*ET=IQTqWDmD&XR%QsNN`>s!1O97pM{PD{uW@)S(g(zt`;v4HDDrhD zyAF>Sq}5Tjw!76Y`ls&5WJ^AmDywXl9#|$D79d66%k-_PQ4^g?B)!5g zg>Pba&z@9G=x)fCDX9qB#5e?3uS4n;H!H(&0GC_*wZzCSC4c_k$&*U=^*zzIJX{RS zZlB)rXQGv(;O#zKJM~NW;SvOS0|V0>ma-Ki1y4~^H(jJ1<6dd1d%3PLJ9OF>4zOJteD9V5JIW;5N+E@_xYPu;0rvW6e^6TI zi&bvC3j8R9?RTmq#n)Ww130!r7J=7zW8D<`#<8}X?%U=3pPP#j1h5a=%h#(dLDleFrsd_FcMAUi?so?1txthHjQ6We&_sjS5$*BR z535n_1r#}JI_wj2F-CvvvLI8eL-XR31C$~_fFqkzw4jA9zYfRNK6gXVpC&C^7}A*x z4SUSE7e6SDz8oysWM@dkfL5cCglV`JlxT$M;R9Y-3itRaWgoJ#9CfcdTStlm6w<4e zAqKa0Z2UC!5Y8mzdY5i?0BdZeekf#^dV>FOyYgO28*8qMXXk}3j)`t$o@YfD_89d5 zYA>iuUej5(Jca@JDEa} zxXR#^T_gq=M*?-f1><=k)MM1X$*uAyLTO0~@9JpT(y!f!BU4{behZ>HmCfL%HvRF2 zZJWI-tKEU{ALo^h>=KX3?o43NWy42U@_nJ_-tt_uiti7-)5xi@%1iyTwQ23>l5-B_ z*e?c!o;zqTy6w}D=bIO!Ea2l)PF5A4~2N8$0qNUKh39Y8c_-WWTw*;@S0SW#fXfe;dq)cHmHmSw6(|UjHCip$nd@ z006^vPyhm$2#YoODRA7;x^eA_Lv0fo{?O?ng@3y z%Yj#!DAbyptiJwHq@XqD2f+%%m)-K@rd8q^89M0op%`fVjlCl*K}e?qI};I^urrI+ z$PxqnUL%rPke|bA1Quv!C6a&uTxMB_|I|nck1-5hEKiy!AX7HJ6WixcJyR-kDJB)$ z;H>KfZ8z;1!2yn|fwrz)FRvd-O(??D>f5R#QX&PJm88h{2bE2^;*IlOZ$w;Zmw8tgzOQCOdFG+ofIyx$Goy+&ttU zZz6x~OSSA8FN}_BN@Hd7^1e`iVy; zGU7hcrofGhmdDTuG9GNrHg+%K(({x67MpnuR&8{Mr_C;L-6l&$$v-+|ug;~G=-bxS zgJ1F-KHG`(PNI0a)P!8qdY>KN%;ID4u4)|R-cd*UhR?s|b|6bQwv2-W$Y4x04)cx; zt&@HvTki!f^$^~(PDZkbpaIvemq8)k0dl(3#n#8doE|vKtXuEw<-5}?%PM-RCy1dc zk!J0)&CmVK%~COySljr0>mUl6sh}btUWbu58%glBH*^gp?d!M)thC6xOd}m$j#e)< z>xj_M=~xECMX?eg)&*F|+~a_HG_rwl`|XGIPVJ%xnM7?LlNA+gwt4EF(LjFE#b#_c zdEfLiXJyO;a=bR9470rxUj+ znJQ86WVTO*i5#{8hM?g7l}y0|fJM5hgRS1bw~J3QTbln(_3vcsAL9Cs&qv`6zs2gU z*cg_qC;M4mTBAmZaUWVO=fY|bm71p@R6=IR8K1PG-z)n2wpoEN+d+Henf?Bi8zy1N zIVO!kgK}nI*OJ&Nc3=i@Xx5buzF3x`7yG@l4-av*3-YA!PFb0myc5NF|9h&)(OJ3t zxaHk*Hq4br%1tI7g*GHaKhT%!cC)yUqld9)T%C$;5Q=Zl#}ui`L1FKDUobrn!pXUv zbw#%ayis=wXjoaUg-5jWdaDbnEahUk0&FuQ`>v-YbwtjAh+w>U;E= z2j0ph@75tDx1^B!d>Yi#CEru_?93Eo{G(cOGe?-yq^C#dpP`l9l9QNj`Br-zqhSXO zUd0{Pj!T!8f|rQJI&w39VB*}gbE-NOfX&<5mKTAr%t=a7vr5!k?!t+C$Yt8|w(F9Q zn3wt&_hBiJz-!^J}LVWIk)M&|Rm7qGH2P%FmvFbmSL_Fj`k_pea*X=2*@X+){15;A<{ zMA)VBEC7oEMe%FfPuF^nx(7)0UYx$2%HE3pbCVd_Tkr_52{KzlOz{clVQvE*$T&o%lz>lh`A@dg!85 zJANdrc>9W9>gRUWk-Lh(gllTfRp2huVsO5PxUdj_009a?IC*37W}G7(=GP99Z~xe2 zu;?4j6*@&PPH(l7Sth%M)G>zWERdi;LZ^>1Q0boR)|c6e*6My+JO5&Q4gO9M=cCDT zUxOm(c*87g%e3_#?>STjx{}1t%b3UGGuN)F5SS*Zs8^OuL_+c5`&Grm18@Nb0mf>0 zFs8A6<9exyy9EUF3+o=XD5gYB%;5XifzDi=f9Kz%7fM>IO3PelBJQ+dHq>qKc3s4B zwo^dPN8^+P9>I_yax@y^>xnHV)s|;_pL=9xS8GGwW3K2MWcmQB8!C)2mxG6ZjSFO~ zY!w<|>iZvr4C8N}RUk6mDU9>#@9pqbL2{9MvB{ein*@)Vg;;00aY?zI0Z>f2yLN4t z{a3(TF19nL>u$eT-VXv@d?XYy8YL(&TJ>#d_GXZx=%P&6dH3H!#8mTUy-7HO!;(NI z`!;aY9!OAKhHKq<(W)PSO(V_Ff<~hEazqHrYIc=9g{C^{yx?1Q-O?GemvvQh+$klS zP;Dc#!JNr;|F`~BfguH{b|C@*WUY~^EG3eNqLCO($-wGf&26f(vcMi|7wp*ivRd(%|*P$x4PHy1Q3`oH}k z9!Sg?H(;44iTlq!oAN8gTp!001N8bV* zOS^+t9Ao~xH8ZEAM2q}b6v}~Z<4$0pgS{G`3OjUFd)d_A)tqb_O9_CXFAN9CZ2T%T z6N|LGDGNmFrueG+^0X&AP@*G!p~HlJTVKII4Q7e0;hQ17LI&An`UMvfLg%E^1abMM zftIU4fbWoo{ul;}TzfhA?1l={khrfsrjK`@lAaTA zo`hc49R@f&0K9wR_b6G;Cf@_4HVoj1-U(Gx>U2;5YKYMe#feWV9}q&ocSESx>d`Y& zal*D_cwmAeAI51O(-oebt8HiG+BBG_SkF|S@`rmX2D^-jwCm(Q*~E}%ehz?i@#shL ztAKd~^>gx}2C#jv>Cxl&=BRu1FFNPoK}@K}hg~*(wi{CNq#aNYky>V7NIjOJ>yQ)9 z=@dCnaJ1_3^{7KmW{ zqM&->{X4L@#f7w9=dXgurN)A$2C6fAyNft6{7+h zyyz~>yc$3l0KitX*t{$q#v8p(*JZi9$P8w0v0k@Wn<=YM!oY}y)WH!3vDMu7hN!#u z62->MW4B{w-~0F?CoNHH)>IctzJd`LBoPh;IRWG0>PQ4CeK<=N7rl+25O$~m6`k+2 z_p<|A6v9AsTxQ7OERK;PG4FXK@rBj5FjBSA>ciW;&}}qIt~GNVsV>y6%c#C_?^KG3 zjMq7anYU-Da+BR&J@^Qh(LT*9xs9#{YPldiau8nSXq`zLp0DF^v{B|cbjck{D1krr z>Urquh~u#sA|jQq&sIPnKnK7?L-fLvXFEqtPoxzoc+by0g>5RS3%Y2is;H2V79|!8 zm@y1~p}+)0Iu1b*4Wbb`^E+T)0$_n$uBc!Lh)$r0Z@h>ATTP!5BWB7SXAMCRfE55? zFT84(hOF~iv*!Mf-3OZ!Ru1U`5CIPuhX;iE_op&*1Nt%3H?fk>mnkvr@jH1V;m4?b zi=TWkbRTiGck$acqDvyjmp3+hi2x_s96k-y%)f@p_i5@HxL^_WuS<)xF!iS8h4_`fYBgQ!(iedmZ5d6G3!@oA`q3s&_q`;olXG>p~;&NSGiA z0jwy*Ll_K}I{Aw|ix^z<8@MdFF?#aRs<$j^uylj=Sk=Zj2!-u6t&tS*3LiEUp7yy4 zWBL1Dt5e!>nA5pUBzaY~5RqM5sjaA^DJcXpr*xjHZY6C=mUF&& zzJRu@TzHlp^s~oU@)`egVo&@Eb-f-WbaerdIcxIQyC4JfIC}9wLz5Z^W~otM`O6Lb zYXJw5C_|iNcna-vajzm1(>*)q`SZeuz>Gy?5fD+D$jj`yKhphFPP|;AGLSgi)$g#M zMvFPWd}{0~6gj6h8%(O>^>Lljhmq^(Q0@&9kIfkD$hk zv6o|u`BJA29)jtTUlyR)Cz+z?k{B)6gApJWN(yfJ9-&(Fh81T5_JoHd3_bG}ZlttJ z(%oh$8=l6bS59%Td)POux|NH&!>)NZyoRHx;c&P? zkh8Y&N3h{-be6h~W}IkC*)KeF$;;vfKxo8A4o1aI5l65;o9(z!@{6MSkL1W2B6VyRxN(isbc;GqQ#0oe^Z z_*L{%OU)V2rmiAbUX!Q?;yea`q9Q|2AgL5MxO(I@Rki2+Ty(52d9{;Z$!t&KKp*yY z%`tjH_z2ID51^iHi=cuBh`$!(I}T9`Q5~WrL%4`{qeD^1^p_5%ZhihI6{ya7pNY?Uk)LRh(8Ve{i&To=|o5Saw9fCvo^D$XtB$elGFkz z)k%NP{pZ9BSB?+J7?;=dXkm2asCh@G==qX)%~Fk{2%>WpTHFN_GvDD&P9Clvl9eh1 z5jDTIB-93aI}|Gg0oyytU~CjLm^2{c)CfQI&=C+=C)$P;r_K8#SplM^qFPZ~-&do#g|luCi7Q^L2Cta};y=dizaVfT(Fp zQcCwc4(tD`Vs$)bA)`8dWM8&oe^0|4tZXJB7dTHWvcnk2T_aRSjUs~-`j-TU9$ws| z*2jd|D2`@dMtkS9Y1vH-v`l8Mqphr|9^A@`XNHKjNRrENQNTihD10=jVf7(=@74|fG z-v$akJ_D*1zpZ3aH>T-#O;Ua=pMJGw3>{(3pC=&v`SATGGE6@PM7+N~W!zF=AFi&k z)aK)Ur@|rdVbqfEnbY_}19eD=Gn}3J(UFxD`bcfE+%R~J#Pv&( zv-Ra!^G;a>dHeh3L76~2n_Eka$a+#wd(XkF=4AA(`YY_JUE@l)b9x9E!x>^*&6gqg#F--X1YW$I}xm6yOe zU#NbDC7ol4_Ve$7!qx~VDiH$&^aTVb%z@BapTvm6#f9zp$n5Mz3dbo|Q7lqHe7d~T zUcp~Jqjo>KX70<|N{9(VM~^cn>vWO#`{x#;i^)pdEVim&g5O(VpV^zpQH6QNXHV-@ z6;z#>iL25=*R+KN2clS;A;8Rc7YO1cmB$>h1N&oP@}S%o^snC*VdiVbhy!PpNfZqE z<}!h11_5%Yx}cz?9AUEsZ=H4Y3yhfNl7}@{FgH&>5o{|tbhsiS4K2u2#fIH{f`vlb z$1ik83>m609r<-?RW8eGG;`PMmoS$R&K0S&GqBb3K~0Y|D&B!38=88$$IgC)@BLI~ z%|#bKs8TLI=&}^7$P)M{lE<5*?pvL(W9q$GhRwflVGcVIekTXKDB}GQn6MSSG)02! zS2|L!m8F_tLp3_R9$L{QCyAC9^p(`W?YdTN47gTlo{T)Ri@$E9F+4ucvitv73c=$a z)Yr!}rSaGPd!b*+_nQc+V{U2=DdvQScFCnf_Brd=zJw-Zcu;3A{k6TJK(mn^PiCzr zg^SVjDn7w|w&{zyJAn`bZTtUEJsz%?{LtHOk7^o306{SJ2<|YqPtvZrqbTqVrOegL zd=KDCb6D*)Pj|78M+_~6pN-GkzxMb52ya3rRA^vz2|MI;%-Z}Sxk=d`jlK$m823-) z9N7U?j(c|6m5cR3o#tJG&tA9&-$P zfDt(suYKdjPn?|QgeAwZ?Xc?F9ib2|nS$BWK@~g^zlVAP#7r+70;y*P0D>Io1pX36 z*VIgRT!V|qeA;yt{RZJTuC%Yr3}N>TAv;!l8T;HU#%8Kq9*-q__ao(ld#W$ccD`ax zl#vtr&Rt_`C(FibJwG&?aVI!JEiZ2AO3Gyi;5^aR#HF8?(N61karKU-qyF59F7y6Y zn>4q!3-wgU+dJ%>d2D6s==CF{R3iY0V1W?@3_=i*Ali4k3A8Uk!b|ojtt)^Ig2xa# zf=%a}-0j@v>N$sAVc!zaPMJIE@L{ipCCZnb0o7qh#ju@LUt17dPP&}?z#cg!qacCw zj8SB8p!OC&$=pIAV|tq~JWOymu+{hUXkShgYKaq2x>^h8LGMjBk#k)Cq?xp(A)$u1 z#HyL#fx;|To-(-mCV=ql0fPn=lR}{?>#&L_0TA)(62D1MgC?Jd0MUKxP((w4Y@wKD z?69r72}lYYS2rcAEyQq|yi9hGu=0h8wwFbfLi%4y8oxxQQlgC({Hq>?0pl@K`Ffc$ z=Jtv=d05*&6z-NV%@#D+#O{lj5CacA6Xs(>mDUEW-C*ZJsL1v87rv`qRQ)G-1L*{N3o)iC-Dl${3v zz_$Nc(;1AGZQD2z+=Hn!=H#!4?I)iZCTR4b1q5K{Fc31HAj;or8Gu00%0tVWd6XRt znMD8cTUW@siWIOe>k+u`UmaU$&?X!oGC*2uv|x0`#}S-f7bpDOh+|%=kE`#{C}35{ zX*vV}DQ3+&>I#%KR!wV1XMh!U$^FxjTcQS1gC&uE!x@$*?713am}wsJO><)Uao$y% zu)Dh6X_lxSpmoZMAzG^cNH;5xF@FrxhOzhkJtis9&j&G&<{m%d2BgE(DEAu~)&z2% zj_SgB>g69L|9GB(gn`CDf%IDxRzepiroAVcpS$x~XT^R;2DEwjq5qF!tk5&Ert#QJ zdHS&i6n$k1Ts5ONu{lozT(yJ3cyZ6I`yure5frLvp2NqX7kkNf$Wcv*akmuZYP96a zR4YH2$=>cnGFFRkLs=>TUzJ}Go2GMq{5~5D183|27Q| zCZR;EW{W&7EGVv+JE89Io~@^HFS@E%t2!BjRf^F(EsQa~UrWNU_PWMOc{FhQ%hn-( zt-BU*DfPzNew>I!acJCzF9wtG4Ah0mKD$+s|lfyBI> z6!w$Cg)2woUMA!)W|TF$<>`^)yPtg7fmDX?S*P!7Q8|1<0D!{ihZSCbWxLX@+bWkY zxZ>~}m!dD23?$ZA7}81n9F&#!M>`GuqqO&#(*C z3UHXM*=EA%v?sPM>1=5G4#q+Q3E2x#3qz=Et*N zaUInl^#Ndf_zSl7G)S7;^xsoRc$Ym>9ej18kE{F2PFgAlU}+fu%mq7mj$VA6qLZpT z0~jyiQb{x1cQk5=vRDzwW{HL==Hny7G@mb+m7T@m29DK;gCmVzN=0dR)jF)iB>Q~6Jc`MhN`Q_(CU=o+e>bz( z$3ySeBlJ$j%<%#>Wbm8j06##$zaVwp-sX$J;@SBWrdRh-vp?Ft<`I4Z?Gj4r0dS+~ zK2JxcoB@kv@&|HgwuexgV~P%*|2?hlk9VHSl4JVw;H4w;Q)-YA{qP99)u#Sn=RsI} zg5Gtkwk0m2HNTtr*C(HMtWCPz`Mr<&J|D+mU3kwT!ibvWmgQffZ(q4ty9)Nu2!)Q1 zJ7aMk=)wup1w;Qf{P(GjlolZ)&b4Wm!B?<8^rt+nQ?C6XQcnR zEreGY8mo{42vj6M41$SyK%8cRHk-H~)pwCgd7jg*jtOSZVo>+vBgCvS82w}L9}hLh zV7p=i=c4N=c4%?j@Jlh$kbn8Qt|K_aR^vX^!WXeW(&rlnaZe{MBvWDGxL7E(-19Ef zNs;l89*k}Va@$j-pn!P2_&Iv~VPGQ2oOcb0LEb^`HE9mwuTuTm;)pps0emMZ!9gU- za{Ikr#stN=B0;bgWNjAbKE#iR+%0?48?J!1h(V*iGd*+J9{R)66XJutGnW}$%_HUr z|5wmCAwf*|tup~F73I7?l>}{f@lFxo-$=5;m!d5Af5tn-H^_&f$^0!hU3ARSDaRP= z%KCXv^#&?V)3xF^B53HbRW=&cbw!a*Y@qdkyfVsXd49|<#J0$-XX^IfONTP-Os5gG z%Vzk)VPC0s+Yp~62<(#kr73Mzv`v{_W@AUUaT^cvW>>wU4;r8-fvnE%S(N%Ril*K3 zw4pNm4%je)dGrBR9i{!$!VXY)j^NQa4%#H+-t%FHj-Qk1ZQHN=ID-4bNetpd+#~HJ zveajkYcQs@qPzM!;y~PXW@bm0}I45E^V(0ii! zk5Vf(TR-mN3a!^GZ^k+mC)AW=o-8W`hx>DHNmUm}iE75c>z2fE7)ob7nQnYjOhMeO z`ah>GxpKU;i1=fH4;XOfS}%Po_de8&7 zL-g3$N0A7K0|pESgvz80bssqH+mi!>NxD*-SY&oyz~_u$092W1U33Pig|JKDAQWZ@ zh&nqEV8MVpBP1>yS{M5qbO%HzkGPlPv`*QKZiBNiL4FirZmBBHondi2ZDyTX6i?_|$MI6)dp0v-}voMOxR+IXXeac?@$+wNCM;xF;? zhW;m8cH)*LeD^UnApIk3wxIzba|h-}TR+Fw{`9v_R>`s(Tn zg=Q2SIyQqc<<(I1hdzQpRJMzOK!qiDG&+w5=rziJE@!!e*#VJF-NHcop!^A)esAJg z6N&>*VQzF`R?ox*8#t|Omi?g5r5O*k-Ipg$%%C)j_ml_suR|jA69);JCXo*P!zYc9 z4xz4we^rb=k~psDOU8Xy?@|ga-sp2ZmXc{jGb!rV9I=Y?#`PPXZdZKyXttjcR!kM` z_vF`+K!Z+%b$9(&tXct}-%@BxOY*kDM4~g}xvq1|*=FZm+H(ceeM4ANu zM3`Stif*R8Ol1|&yNFpLVkivADHH}1>b57@EUN1P3=y5I@FopU1|Z)r`fj zRS!aN2?-j}@rjwgEmAD2WI^xjzpffi9)5KY_w2OIcxtY8*vv-S_g!4uv0=iGln0ScDC8ql(%%8tCBm2)YcIRpI7S(e8{kDd+ zJGzxnCCzsxw!j9vSS4PEx6YX^-5y z-h`_(-~Byyvf*8D(vvFW%d8~!yN`3}@q7jKaY|OJ2O^x&iG%hvFFI6^Erggz7$DUe zLZa@aOLhX0w)w0Mx=Ly8*&V4fqtU;eXLz{s>}5EzvSUnhw~_FjY~+Sn;0s-?e-<*5G=VorzEY8;8U_O(So z4~(+vvC>s;>#f=O`9MuF2nm4(^Z^4;Pc}QjN^RqRB!mAB&qh=$)0gBE)Wi~GhSaN> zDD|rtaL@2|Li;8!w&3`2Jaj_{e#Dbvy(GD}#u*m>pjE6sE1kNVsNKflH`g7<$Lwq# z`DwfB>?m8lpof~Nmu*qLdVBd5dRpX3zoDDnI*t8h===>KV|c)`bKQYi^R=jj#}icM6|?!j}WxtgqY()-SO_*0SC3W;V(J34g8()f^R zZ3i?%mETjtUu5j~Nywv|;r#*scTeV2_xa+4L1L=Zm zB*Y0VE8qo()pu|plKpy!_qBjZY?){K#w%T6;#9PvlR)%3BcC-$kipW zCs~wfqKB`Ba_096vjbY5l}@%hoj>v3Fkj(}3Kj+Upb+lZG?aMAA3`9Bk^|iYhCR>~ zb{`cI476n(Oc_f5usl1`mNACQo45H9s{reG#s2t>=g$Uuo3Xx;hMhavOC6)Wqx0Yy zCvq4&QH-%|3-$E{0$qEOUHrWp-pdO!PkRR6Uy8Sai4v%nx}OMI_X_Ie)ep#OJ4FOa zh1a%pPf04`X%jj?u0#p{V(o$ye$lh#UjT(n8!t#dLyylC9M**u0JE5EvTpwmzL>|icd_WyBy!RI#AJa zvY`&8+p!SsxGwB{^rU?aj8M#`v=x~;uli&iv^r2kzK^}ofnagO8xW-_WKtKLP(2_g z^_?yS-d`?5?TL{%xOF*A{0COf6YJf!yT#}^WET6X;`Olo=@;n)_D<`UL)2yT{L_HW z*}L=qTJ&n%u6>;3V12rHV_#{;I!!(g_CHU~<_6Ag>-CguN<-l7%az+*u~f~G z5Q)*l05C?KC;_P=vWuUwiUz!qcC7u?YtD8O$?>;s>Ww*G%U5!z?#k!kJxTyY!5wg^ zgEAvZ5D;JjSpLRDp@mBO{6yFppqE{cm5Wv|AeltNP~G<0eUC1g3*BWy?zLb08)_w4 zY8h{?Q@fE*7R7-PbQGyC?^EJdYn6zxh|KXRC-z z``bT5b;hdgrmIlX2Iu=5J2)$6ZVhfER8coRBCpFBjM)Dh%}EBEe1PWsyV7k=0x6%Q zmV|fI5aAgpSoLHAYKmshNA;>cRhQkFbx(l}+~ju(8OTM1wd*x!$SaRdq{+cuA^4AW z5kjz`aq0AbeQ*e!vrP)@vx?1)@<@v#fCo+Rx=P?G9ibunf% zy@NRLBcC3ut@yuW!J+9-Omf~&laBLC8vkeDuB<}D3<*#P245&0{~6g6Gwfj*_TU#a zsyBh|P2az;hX8n%xcMYM8sTJruuj#fVY=A}%k0oDE-iw3+Jq1BBH}dQ{pYFaIMN1EPtrM?C5_}AGPw3H zTl>{q(o#?l{-5CTaTeW++;RMIQFM=?7x^vqD|-bnfrN5-7D4*_5AN`zd@Arb2T24m z)q8t3LHpoghY8uDoYVmCiRJksYTw8_84w3xA=E-$`r`2CF3G%WO2yuQmO}RBeQmsv zGLZ9fr*G~cYPi?9$&;%;Gs9|^(H#^o0}P?c^t3fP%jw3$>}8nvGMIb2f}ypj_uU3! z9Hw@BhJ+hN{de^R+v>)3zw5K4hj8(8HqlTKC;DyH3!C5BO_N$#vX|BVZyTg>KoGND z>U-~>DLM^Lm3oAvkEQFmLHOeCkFE>|12pFn08<{XWn~mp7wXi2Ob~~_@kkkI^}^a3C@ z3}bY->HA^N|}$K{q?uKTTEq)1leg4_vr z&r4U#l+`YkOdu&i017SqF!)oIr|ntX63eY|OK(5LAvI+-9!KAAx9jA%ivGo1JbmXd zAn<&NioBz5Whf>gQOkBr_1!W#_gRRpa3a^p&g(wd`gb}MK_Y)=>+{{ys|QtdRdg!H zltS!R7r0%iU7Sk^wG@39uEHiIQt=P{xhF9hoSHyhUwEu(D#s~Ek}wQeqZ}3s`C#IYYDC zg9c8xk%k@EU&`}xq%QpZ88Urz6#!dbPRfm zG+9I(nH(E=Dlc9n`}G4Q@HY=8ANg$DFY@#56mm#m@)Mj{h!6nbeyafVe`mP8glI(wGoCYUqct@CBrZR`m{yEOHKt1sd}@ImXA9ySYJ9W&Hp%f={n2MXb8%&!5^iAo z>xbEW6lbjY$GUz-B*J%I1bjM{Tl|HhA0XuISV2d=dosOoBMiCv7F8^H5Op^De6u{* z1H=)mb1+md=?B+cm)Mgo6A}>&02wm#21urR7&ksl< z0wDR#8hs^zX$14fP6ncitC$VbiNIg8uc0Q+&DYT^d6E^ z;RU{;oOO%uoT3a{4Xgy?jTXIJ8$1AS1BQLWzU?X5C{e28r*PQrKn@a4;jzZ?^y;-n zVjwy9zdN)?oF-cPJSgLqN(+)kKXr)ClZ!)MqdB>R{qYCjt-3b4HdiGbRl9xQd3Cn> z+(C;tvRcksISMZ7v+FQ<@q6!1)={;@y4?j${JNJ@_J+&c-k(G2D0Oo&JznIjc5^66 z9YEb1%`orL1kyyrb&ds&V@nuxErhL=IP6_Nx2%(^uWA-AG%Qa8CxMzL3*=5Mye@m{ zwzKv&Iv{oF5Lt`no+}Y!ZogOdF0^OvD`8RL+;lIXg$vGkJnWq|1beEPF6_v?4VDop zG;%H>##|-Uf(QfvO|t;2*&jy=_`N3~oB92d2)Q!le>c)rL611w8XDWpP5&F>S>~7j zJ6Mv28UL%qP#LDW)ds?={Pr_(_!e$e^Lq_uaY(Py+`P{CV%Sl9O+KU>7mC_ReY_AU z_o0zTG$r!AM|x8ZR$p{GmQW~g3eEDXoAgJjYrcQG{}wK`BAi)6)_({1;yN> zDe%Za$*+P)$Q+$GMvCuoYkYw8eG$`#)l{ww%(nM)r|urgcaIKt(m-1MKmlEnhfr-8 zIuqeevwlp>A;k7C7rvTLAA*jBIcTel-T>J%1hwabJBq-Y1}iY3@h0KC zLi>*digE^ADLbkas}2}{h>t*8V|>zPjz1p{?gq#`GbOpu%DG?CHvJfkhb+M&DdG;p zdVf$uUhChFiD6_KsT-V2wYQaa`?nUVypj;41C#>)YDtP`Hixk*;vZx`1;R3`+Qn$$ zB>@P+7UEz9hNSK{{u?T=Dzn!o0$?Cg7_7HY!6X7SAi@MPNR>$-!Kh$@k_|JO{GUo8 z-q+opxoKp$9}m7_aaw_&JinEYEfVxSY)T}ES3U4FG9a5K8+TFc06AU+n$t>2*@T!p_Q2c0%{<+I8mPK3p$fv}N@qn!v3k_zu=sN>p|O*O~H{CPx_@ znI=fV%>UM0(FZz3Du5@iA}Pkzi;F+7=~omAWmYf|WT81LMvt;fKkps!q~^#pyS0315}M_9FSz2i0*u@Az_(i z(a6H~8+a~_uM^V9gTSpVOO+DXr9fd~G|t<}4JJ%`6Es^pwbTR`WKy@06oOql*RzVa zUT&-26lR8>r6hPUt29G~RM^A-f^PTc+Hs)`w5|)p(%=WC-)}JPuA(YuqMOd>I}J+d z)lo;@_k`~na((KFRQI=A7D{K6BNX~{x6pq&fbN^@iufdmhEX#o?@nNmhG#<1e65kH zMdZ+vz9;^frWF{52f!(Ul}^EY;;Jkfrh0xi4Oz|pRP*~I{)O8Up5j>Ao*4~N@3V!d zi6Ezc0+Z(Ho=EOK)={vzb$Ucuc6IgL<)GLy&SziAy`5kkh<+|BPB8ZhkuSkctzN&)OuV~T0cN7e;g{rp2{sWp{ zGu_rYa||bn47TY&C@Pf;6F|UgmyuQwI)VOc!b+{8Bz!&9?~=#tc{9MB2kfviiVGGT z?i%=yQ`32pf-qxbf7<$$UD(2!ZZllbbbkV*JY~*rvsr4VD?|VcLCHd~WET?I`kH2| zOg>l)G9;tVS%_FKEs3#>5NKql>u>Jpz0H4?5<*YkC8!l%$wTDkfq;}?Ai0Nc zHbw}Yghqs!zC@cJ8H5&}cZtfW-{Jlhdwmd8*Da%NwOTzhY1P~8XCo5*Ayb)9VU1>Q z>=HCS7AGnq@O}+}ee|w`n^=5(lyGi)N&Di$RT11({0lWE>&DuMtUe7Jjt_NQ5vfa0 zE4?3dcQ~(!Z1j}?YS3#ag7`c4`5NeaSj-}+;7&`>C3_o3mcMG{F^BxH%sfn;f~TCp zNbVhaLveU#-bA}}K{b|r$Cl6%Fu3UD6ok4X8K!4fT1aJ{UEd70ia`*v8#N2CfnbmvvCdelzi^ICFG>rdIjrMEM1r5ndtJ(_Z)P#@(%!fSuyep`|MH+B@`{ zt6$bGMtj{LkpS9cP*$us^eE(Q`S`)08|$r}VM`B@mM;hc%jfZ~Rohqv{wEWu-Xxms zpwPLA=qp?HzYLKlZLpFyILKz&`cUwS&5ln+k0XDyw~cE_h9)fq^6HpCz1ESb!orr} zqq89Uls0;6VhcPTiyp^SE77pa#naFwGh>>2IFfWfp-qNn!}l{JPhZ? zirT642i0cSeC&Xm#?go|nRo#+Vl!ae-`Y&hTu1zB3ZC>aiV_70KD@Lj-drtJqw(K81=WQ-RE^ymCkOXT5=@-WaI zo%#lvT!GM)wVEKNh{|;+G~hrcU_XFBI;{yZ1*GszlN7)0iA=x{k_RExIFplEOfPxm zhqz4v(-LE4)Cfx>eXb9Al|6aRT1(8%+DU_pHW9iwJ%4I$L%CZfI^4C`akhy`qIII> zG06lSi(~bwSp zt;IYkPHV67I+8b4pII+^!qOiA4RbNr%_mSv>*R&cT=VTYLa7hN!kO-)C(zTk+#Hl$ z%3%3J=X3B{TU~t@Ch@SHdX0w#GqqHL^-N|>jJy6|cOB-^e*rOYXq22Cq~wx9Y{5S9Jv$*?Yn;nCyxX3-r(-J8ApIC%wZ&I0Z>D4?*uVyz+? z45Xyh|32}9trRN+YEXv@rFWl0MITu_tOQOmVEBId@eCn)JBbP&zj|Xp5Zqzg$IzaK z-A}tmRQL zd%G$BHBkvzS>xkQ^kd=k(&}}Jh3Rk#Qo!zuQNqOa3%#AT57f1=Oo3UG+TtL7i|sv)BI-?r7(}>6-taJrRi0&-t0 z!0-$YgB$EcW?!RnmPtK!oYlr?wdho~gI!m>@}A{c&Y!JuV;2`5c!Dbqd2`aO?dq`W zWdF#CfL6J$?B;qU$&3aAd3Ztgr9y1^b=VN#Ul)mR`;7T4J?y&fRHK$edaSG73OLs@ z96LhJg_(VIMfP~8@?%)~V^_yLZHp*1)Um1{wseEU?N8dihssjICKPK9VE-&8~0V3{QM5UzPOfzn3wvz}bOkG`OK-<1U z@6X+4!S-k8xWvR|kp}N5;o|fMIo*Y!mMbwo-}m5UhQ@^hm;ZKMw~^n@UPQppA4^`2 z<^NFufw5kxk$m%-UyJg_QYPitU|KPM8!W&&UvGG<>dNgDM?t5;G9Pck9x+pR4hM*^ z;3seALu1o4-RKj-HD0V~7hem8{YNi04_{bFrB!=@T8aWeOqVaRBr~0ysxd%Ug58iQ zir!}Q3nJO#<_iiDniVi%v~YP?nL18ofYnS)&WF1ob-7&_3aO%H=|#|FjDr zedagME_oIQdjr`7c1zEy=-OQj&SnOnk>NZ3nR1GZq(2vT)(1h|LKxVFaCk?AE$^xP z*oxjiEDWAdB|FlU{qYT;oCpy5S7)-Pp_EtidQvms^XW}GG7t^1TW^2( zr+?_tG57d1>oj&6X4PGBjy**LFh?(x-c)OOtKKcvk52U98iG&$u|B9B%)40W-AbG} zitY8CZEHVMBnV0O@~ICsj}kOFR=oDE)O3GZgjez?w<+(GQfu;tcq+lh_oG@vBVKYG zdrcXypf$_*%O>)%n=b-4dk_Yf`W9Bjy!Y+ugBg==uEkqMKOEr^tOuz)YI26lgn%EQ zDH3b?(gqcK#Gf-GXYzloHSML{6c58qxa2F!SUEcD1S@b=yrm2nUyOlH!@7lHvk}x2 z;+KVoMd918_u>BsGn#DqX|(4m`;mbxs&T&)?<`7Q9DsFWTMu%dh2 zNFzlFI6xLPm7FXhCV2&!*gA@1S>#h?F{<{YYgG6EjEdSzOqFE3$Nu`#cIepo#cdnxy@9q!*Jnqq_d|LF~ z>ZK6~0=pn5=4Xqnl)DLbzra03m9?cK%7eGNzQtJSh3l|!GY}Z`1|yRtFM;zu|Gv8q z^O+Fi&ful`7Fz$u1Yp0oVZ^Hq8&Nlr&bOp1Q0p!6XNKwizI2b8m@0g5)d zfCoic0_q6f1iods(80i5E^FMsaTd+v;)h`FeYYB78`}bElJ7%Lyz0LrLBx{=T)qyA z6b1fLH$`-+U@cZZu3r=DbCq1=d{m=LYt{v*pIK6eFlILK9ow*!{Vima+pAyzV9H~g zb}3Z_-}U*lt;WZ&Znpl`FPKhtrRv%jiZ)w)m=KEja1gQ zx&-Op?Ka(2;u?EgoGE0a&!vxi2Q0iQd77^To$^}etl!a6{lzXX|E@qj9V_L7tF)Jm zElb9##qYNrHWAnOuM7LfzI$bZwH!BzX&%#T`R6v;|ZnzO$%oG zCh&<^V^)kLP2{avrq%rEP%R}*xPHkxYobMl`_!Dj6iq1R$!lJ3YW~?{7{3>)7T?=^QPMnyjT#z54Ofext6aa6VI74TUZ zgpE1`jOv8M15o2RXaW?$0g5tI$Dj71Mi#i%(WkXX2IajxPuruc>|%;jFyft)z-o7& zJH4gA2Gyc6lJF=Uk5!BgY!L@9t~9ZFl;GD?D5y$0_YbIfjB>oO7>F9}y_I&wA1 zXdGF3Oa@HeW?W4jV6Sl^Z}^9BtdF_$F#1shIxB!>`aHm^_d=pSUJJo6Nlle^7?P{;9<3}0o2Xv6_5ez()rx@ z3lJk;fgxG5hARk`Pavkqny6GHcT9dtynP+pZl`XoKtj)o;a5^gFouf~s;+459SWpo zk`gcx@g2zU6*!E7U!g;0EyKdaP=Warwm8A<-8E;An=L;R#*|=>p}xk5S<1^fkYMU* zZL4Z%Oe-n>cvsye!!p5zH7Q`LybT1#D;j)kNYvPCS3HQM3@L;;zLma~D;}$VP zfmq~}BPR0*>@Ycj2I2lg-(UxP@uIO_r(sqZSj#u`k$<;b%^&KCj+KQF;P zX4kjM@<`$0RK9HNXfD+4c}pP-4b{pBH1lcRHr;>ww0mR6{QLwjE1h^Ru5N$_rXcGa zYO=xsduf*71Bp;HrCcCe@KR%ts|doDp5Hh03Ng~ z&?j%9xH=9L{id-Z0JL_cBDWAA1v$03oz8d6EkMr+hZR!hc{FLs=zblplai`P#0JTn zoQO^MARm4~_QiQ9qHPvV0jFhdv;2Y>3@U7DCKH!xvBSMKzeZE3({FvcJHyza2f;Rz zAM}OkEEo;GvJM1UsAn&t3Q$++|OKVgEHcIL;fz%?#5vmI0a2EIG5 z`363(67YM7qe!hD4b^)LJ? z=qHM(0hU_4Y0y+Dvq<0P>9&=AzIY_OzHc+Kx91~@54YSw zf7_L=*ejG>Y?%)Rv*65vQS1&0x@;Q)15<_E2n7Xx!b!I2L&b_4&*DC~+2rOtX(Uo5 z`~mO&wTo}aQ-H<_dB!?U6B5GbjQ`kDiRYn7wt!@^ZJKo=P+9Hf&>OQTz+#Q3>V#F z^qw8B{p4TL5A65iYWlN=><6}k)mm0hNe+Q{n>v3=`oX|}HsZR-oP~p!AN;!ocF;eV zxo5_zShpCKZ8D8)uB8IeMV-tWGeU0Y2?g}T1Q6H&Usz*zr%Kbfw%(CoDE}RH*V8H2sAJ-{1`gvy3+#Ux3!3ZI4 zrsr$O;S$&xn)Pqt3>s>)j0Iv%sLm( z@!RmQfG^!Tgwg_rbaWTd`4-LJCi3pf1%pcpr#`uozvZlzZ1*cIkDdI3CKF`;2sO=&0+27{;j@q{rYV5}$sB}1+^`TrjN(4&Vqq1vXj z+488e1)71gN8}ViLi#}DSN13oxum2(Og%)d3X@C5Vd(+tR+#qwToVE8$PO`-*f0}< zLFj%R>_j$SGwUzACsq~r6x4Kahiiu8e0Tp^tg#A;b@gUCdW;iIgmcm>RY<)NM~*(3m!A9`VHvNRR7 z)IDGX7-4z;nF7e6n;ikfZ|YbW0+T?}1ZW{NYY(XIqsDaNy3_+aPRTMr?zpy+=d#oM z=nRpu7EYX@*I&V+V9DvMPi_bXCUd*3gC~8>8(|A=MKl28V?+65Fw9I5#2FqSUb8x0ujA#^%~;DFle)Xqh&B~VZlT7&5c(8X zvXACn?!lyQuKoNG!fDXLHI{1$IeDjPth?F-#~)YSq$F*vz@2G&D~`c^%drLqZ(^gW z)j=crFWW*MZ&Nc+k4PXP5h@4a$s_@JR4BIpED!(&n4YouJWhcP?JThZgxK%^L7+318c7H93$T#!CAE>W;|SA%*RD;Sd=CT z+eE#+K@kUtNrIGteB|LbEVl@l%>8VXtMH(0C*^pwgQVLr*trE>?2}PAP)Z^Kp?dP} zR1q2*=7%ALz)M#9oF*EdHtn#q&#n@_xV6L>=F|JyrHwB#q|0z2o*mNIR{w|pRJP87 z2|7HEi3RX^mm<=ntByTcM?ee^?;D7lmHB#mU1ra6&>R97mjxNm#t+?b#z0*=YGt;v zEvYia&nFmQNuI<$o){nCjEumB5XIyN4<~a^%)q$^G^e2922gi=5i@rPCoL4_?HJ=7 zRp+8E6Pl3>ywP6I6(P*2YxB5|bE8 z_=`{cC@WCP|HT$0=_qj&-CBT4@r`}) z<_?H~euw)1k=={RceTcWD*LW4zt@^tjXZWX1g0o|Lz6B(&nOzC zx6y`XGDmTi14uaiUf`NGi=Wdk0KGm^B5=?0bp;5H@3WAj!>zj5jkZi5U}V-EsViw; zC@$^mE36Rqwn`^m4$2c`w{euPc)X(t(4rI}{;2eO7)HpiZfe#C+9iJBLxIuD!fa?M z6sys@sNq;p0l9u{G}b0~6AOm^{iVGxy;HFS00hk;#WL~6e`)-Ko(plFlj33Cr8UG- z5uP{*YJXQurb`ah1+cP;-75H=omjL7{W!JO&v|KBpfW*>f1{DaL znT|urrIGI<4YD&ugKPOMm955XCU7q0aZdnI=NU8m?sxY7-q4<-xyX3d_N>XSd{%~lUBq4S~s@)}!#Oh2x zBR>EMfCo$LuTPJ4bBh9Asr6-(n3YTLw?{5~-^;vtMfBJF?&-{l<`W{T(G}~rHJin=YmmUF}MsV41^cx zJ4R_nLd&cDi%&aV69*TRuXhz_WK>+&zM6fB6!l}`#W(u7S3MBH z;hrFb3m3lZml9wX8V1okD-CM2JR|!UhFQn-MwS#qk}1r$>#9n@`+GbYn3oe>&o_r$ zfZ#rdfsS{SKw5_hOv64@XpUSzK)au^?Ko{zld#Jo^;3UjL~Q+Vew`>MRJFH;eGJR+ z9k~OU=**+|w~#n~rE;{6vQ9*c(+Bh)XA48r5r^L755bG;yPRel0s)_75Qu1(>yiUb z&wMRoV)*)_Pgf{IcN`+(R~Z1s7N0w(qEiXVK8r2PXuhZP>#^wkT#D%QA&mh7#wbVK zeLM)85xE!MBLc^;+!#??up3Tp>ZC3+6B z&pYZP|IahO!{>$@UvD(jSSrMpof69dq$?o6d;r75L^sJZaw)Z5r#fIE<}iwmChnwZ z&_>ZK7mwWhnWqxHsZ4*urN)Tp1hGY$n0SqH%BSuF6UrXUeAt{m{Vd2n&i6-BKSr9a z{`-^HfG&W54mxqsgYsfbwb;|mgCk&JZpiOmoAVSPyXAimx(=7`vyCXSYt7IlPG9ePAZY6Go3qnJ;#ZA6y&< zfqMuqEHxJo8LcAKrFQg99RTp;OVu!rQG|$CJL>Ik1csIi#E_XbO8BP+hKH59!K`W> z=0T$TaLdNU%cLtA(|g&w{r3Da{kFt|E>uz61k<;Ht*Vt)X|t)Ja*IIgzv66w=tvvo zf0TrY!%28A4GRsbON@Ot0puW3hFRVrkjpCN^E4UrWF1B(&t5r#PJfriIy9NpoHua1 zzLU${GI?!HIVbt#GXpEG%xmT*t^m!_3u<yQT#@VC%LBy_Ke7GnC3rRT-BEUzU$u9pcw8SdX zgthlkE>51+gMLUCLvaM{sDwqrp-UM5`>?;=hyVt~q-1qBB>n#Id263`#2jGZ33j%O zY9SyjXP*|lFRkOyyLY050Ee%LR|8A459h^~Sm*rHS0D4DVl$&eBmkt7et8s8w@oYO zAtC_^vc=z~8i;!|c+g^Id00_a;)r&dTeT7MD>fE9^2zKmEzvhY;%P|9Q@F`*jppfo4O zxzD0a_)?Nri_*Mtx%86&^)TXpaas*J`G|He|evaXJ;+hj(7J+worFzjoy_SFW`AMy;@(L@FuFsd-@PCZMfY^Kjx||8q5M&XNLxI150kDEXI`^%1!84%bd~nb)R;Tw7q|r( zAyf%w3q7yxcBa$sc|C;gOE{wAx*7D{Wt|+VdW4`+=0Xdo!GP3K~W_de0eG)XD=J z+3$bd084|)72eu_0GComc$y7A}3zm-X9P*m{z}t%e8!N=P^~ z3*dPHE`y+h85YSRg6;;;-qp-!F5{zrXQ|@!Z5T>(=-<6OB^89Aga;!#XIEQ;R8*#N zy7(9tE!z?dzJUXPpfEMqX~UcaAgEttDMg_?ZUal8R?r)4IcUH*0CHblHOYigPI_~> z;6$i+8|Aa-!)=})o+R8XQaW8~{QXXu$BRKm5ItxunZG(4eJO`-Z5O}_Ziu&_&|rF5 zlqd&zffYOhy;Ru;?Ie|D>??;9-kl4>O!5DSD*6 z;Zqwz&fKlmpHD9VaJ-*V?Qv@|gf=m3GOn7xGry+*W0JuM_oGOl$757$On6NRo1Pel z^)^|lh5yHV1GN)Ryuw1VTaxVZAXN^J>xqw>eNTtqdYqoFga68AP{*ffqK4$G{k{`J zhHf_(7{&A^-4aSpC+UT#Z2YO?t6vJb1$^m+X#w#L@PzKQCG4;>AWSR2#$@WLCO_5A zSBq59FV$yKa9T;F!)zc}Wo)-K7doR22w>JT_1MYJN4veca}V#(2Qz^f%7S@t!r+{r zoo5oR{&0cZ6~R5_ca8xU4_s`52=Yp*B<&$ekgf=kf91{sx#g;&>f+Ba-sUA!d`BIk zJSma+VM&eDYA#+3S#xvP+wwBrtPA2(Lh(vhoGd3|O3oi=RWVY$OOY(P*8SH>#o^OI=p*A`6 zZ7bYBK#QvvA_QmqAT7g;DTLXw3oY)r~t`9(t1WLk! zQ}&KTj^bqI(;eR`6L-E!>L?g1lThj>ij3yFY{)2swWs3O2`{m3ed`R3^Ph0sw^|tn zYC=BYr$=50bIm04WTp8mQCs<5@(w0%SG9wcKU1~n=29_ntLLX3y<*YFG5tyGjpezX zC#;K&>vZ1LU+-vou26reRA&3_3GVmHfn)}04w%kaTjH0d0AoO$zpE2uVt73ZE;f23 zuFx=S1wtdqj6tuauBwNB_G-4p*Ai*rUO>h5$!6^)ZPw2cYKEQ8&9T>Y_@NfqHWm?; zxFf2*HO-9gT2PTFG;=S2e==R?-Lk4hp;!Ui&Y=!~pPEu zH==zGv=bhU%W-Vo%qXtePPI6V7%i#8Z->pO4%~YrXRWbeh38xCdIfuh;!c@322?@c z_1ih34AqcOjO(q7N#6Ymft~&D^@%LOh#dAOH1xoX+Q+lKXTGJ^pk{zU811O*sSMp^ z0U^tgPKU;(vP%Wx5)HizQhO~83Dm3J1+;5FROg)1qslF;c|a*veUHQTBDJA5{#$zQ zVUPJiy6A@EcC;I{?=Gx5VL{zY@A-B8<>9(1##GOj{)Fa*d zTl*eH(Ke=pDfv+2XF=$FVO7JOOuuT*--L_N=-BL8nk08_G)bCzzcpT0t(CncNJRy4 z3TkHYhiL6N2;kOZp_l z_gL7JEz>J@%=XTn_|R5A1f8q=m}HHndUrL|nI#(xRQ*^~N|?`F3ze{(I}!*m*iSTB z-7Pl87uZn0+Aj(`8X*uGf;uCFxr?aMSkJ7_PNFFO1ScvZk%kIEbC5m>O=M;bGI!!NaBEG2w9f zVSCIk*+8;H36Djcx-~9-rD#IngY&LC_L$Fl_?6%QKT)Yug#Fzb0FC{ty#i&Oyz218YhKo`H4QC zDF6mgHPI#69GO)&lcG0wsf(i6V3c`QU+zU$AfG*RYzp=Fw-Xt$mmjvR5)^ONU8T5P$?V!0^E#g^+7?<{MsuHrONiK!CFr9|gNIfIP+I z;wpGR^3D^T1h1Id_l2%&)OfgdXiVZPxhb?>*@ZiBg=Fir+$i>H zUV4=;2&PQopJJ)XOsSM|(6vBeepK278wh;XCJTERn?UyPkRNv)4B=zlqpP zt7Rx^bjZ^HaJRT5jFj|qm`*8^qW2{LmYJyrF9={Ljl~rQpFuOUB(}$Zbr9T#d&p=* z2q$eEhIaG#KOHXWJO3srPnqm2)O`1a4LHQ%__5OXXbfuguz8M$7S}Z=4mUJpCx~G!*}o}_RgH$t9j>f8^ovaYDyo}@zr-Y zdJU25S_Tf%GePgShy*XNM|wK30<-;{69KBmIqqI#l(5PTb!T?Mk>3lCLLzOI|GoET zx7YW3qe&U6V=>(-UMZg2`j>j3)60L-&_(pTuB_WA98|29)^n!f{XxO)7T^xUo?eZ5 z%?^x-if_+nLqAge2m!AF*FW7Gj{34^T zJ(Uh7j6mkcZKf`BU~pnyo*^{{&$LL7_Hj+R(V-lf`G@RgK>mgP+t&T9VazcAvZd{k zb%Fmx8%RR06w+M1HCCM;Vsd71n-oz;kdJgPHHS-ME^X*4?@x#y1zB#AG}-HX5d&f! z)eMe@&7{LS{)EL>EB4o~;4-E?-s;%A&I|z?P3C{-NHcz7#Q&v5G+q^^TNeoK;ry@U zaGkq}$J4(TO%O1Ua^)(T|9i1JpJC@uLuO!uN;o-6476^AozS9&bJ36EPViHZP<*zW z)QJ7dllHp>7LxQHW@5TtBxbzYkuvZ)=F;hUpW?N>+N%{OvwO)k+?`_str8Bz4C9A2 z>JKE&Z0#|)=RzR+0tkjw|Gu~0!fJcc>;a_9?G?wmq(%dwoN);{;r>K1xxqUVXyStE zU>m#ZK%GVsI}(Z!i95_a;EZ)^h)u z5389{b-Y_4E&E$AxjD0?*{Hk~#|kR0brF#vH)mp4BIus`k{CX}Q3923qg=LS@mYMF z6b1>oq+Sa@O(`y*&-Jn5+R^*%4*eL*gju-|TeCD^JD5~1+i(~WwpdAt-dXLQ&fF!g z#VcE{d3?6?<$<%(46(nP-a17x zPWt_?yM#XH)%rw=l-JJEx-}psy=Ac_TAZN*D_XERy2r~L1n5nfzh_93EB}?mm~#Sy zA+}x*1Fm#&j~%%-oB_Y!8U~SAD%sZ^>X`Fk)|6+dpe|A;Nt35jF!$(LP#SKElqPhP z`IICLC!!)80`z@ksSWdMXme3O4T~8t=Ph01MoY*0gEAs3@h!jkJRVHn?t>o`e-KQe zLif_P**Q4N(SJx-g5>l(lmeHCMg?x3Mx@5$%8ppS9tYvdh^+1?b+b0@9EWr1k~N7? z%leu;zod^i@5caQOTI%UXx09bPo*$Ha2TULCZuxeUKr2eR0K<;xL`x}) z(gj2Er!R4K&@KE~nuY>8a)U$a^K}B>Zdc{1956g#G{(Wg0XPVjO367f zpbHa54Ev6e5Z!+Vdm};8@_E34$+Y`YrC*CYZztOWw6RYHtJ3VXRL)^;IEuxEd%+D0 zfU?el+>~o3go}k`)}};FSnsQh6juOc<9jAkq&dUZBWGXIYSn`W`^UUW`qF^6#k64{ z)IMucWRrx+V}wT`KyZ0kdPPg^R=D!kcD6{tWPjg<6VxX3XkAkL{NHE9&w&Bp1Z-Ia zp7Z7`okWbv&vY8Cvr^*oKb#GS@Uh2(Xpv`lR=6~*?HM*@*{e|6YyyF_bt@eT$OF7BpH!@moTV18hs9bs&0ByML;P$CXuF*flU=!C!AWr?2gwU zfVoY7@>n*7fWs#kg|RwRF^$t=#@)t5Y^skIVJvU&?9ngl2?fv~%?S}#2pV{(?XLpE z>&W(r?bJxrBbbA#Xo-Vpp9k_^hO1QN;`JoO#F6H$LgGNT|26RtZkT#+$JWRwz$$P& zY}0{u9ha+pO#i^q7w%>zODATldNcMB=4BHuv-BYB3IS&uA&$c5w+FIAY-^Dx87 zQ4HfUIP1|lv6hPBU}?cr5_M3vsZ%K${Kqyt%!0_zU%NniCxmN?NJ4BC^e_YkGz
    c3os`h5hQNiG=uExSz@Y#bfC10zeTv5qjwno8tm29z(e}V;o~@F4Sw^Za3L9Du zbAOs%MuXirb(52gB(uiKMfsuH;JI!MWic4!93)#rbHEanFT}RM2 zYt_tWY-474U#uyrj0 z+|51ghG1;V8Efh8_Qw`!dF2TO2& zyQH#A&z7H%wV!na{-E^hO*mo;5ZyimDx5oW*uK|ffU$UA&Hoes)hnaX^=NaViYLM& zDIGOQM^q}4fwLVhoEU@rJg2{cqA+&a^Vm#*dbNmcC0iJXGh&d`SS(3&3c+;^{teRm znS0uUAshL(-&=H>Nc7%EHq;!8eozAc!MCbNU__D0ro~k_yoar%=31_rm;#jGL&!iO zaQOK?%hQTbW@e$1tfVDWBufbd(A;p5?X>C57b@%QlcF%OJR_@rk5%tpNDgC**fMl5 znNR2FMmYuY#t#Eu5oH|6-t)JALlJB7)SSLraGC*hH2$Q*X=zT2MAdLI@(4EDYH7?- z_u@K?e4hY zEP*+2Gk-oxz=z1Uu7oW)!tcu+82b#dIfYlMWJ%@qPC_pX0AL`3uEVI|D@7YwjlL|$ zQu1n+;B^$;>WkrLND%8~d8fC=j!~>*$mX1O&fAl@j#d zXD}ulLRb+xs{@+8SC{t(KO8zV^N%d4dqaF0efNalg#2FiP%C>1K|A!(@QOY0l9=<= zM8Gc38REdy0lri(+;{z7UeYSUk_Ae_(8hsIWU^PktPhLZVmm)p0oIJRHTR)OM?>FB zPZL8);wYKKZx0-OYSxY%W*;CuN))YH9@egm({j?R;^|04>6?MPGY?R6u-L3^GtxDcoJ37T$Q8_{=@_& z#1#PmHbUcIR|UW(C{DJ{XuXt}o+zvb1+j;t8RO%5d-rrz;+3^(@}e~v#XZC`Tb>1! z(E}^lMp_gHuX+`$E+Zn@vWsT@Jhdg4h<9emcD+>e7JHtA-n;IOh1WO4I|iTZ#w2rE&}cNmk?Q@hkK?V#=4S+dHX_No2?GIDk|Kt3^Nrjs`wzn$N4vKrW0!q!zfr z1f0sYh5+8JA1RvcMiEONiU94ShcmWvUuJ=(N`khU_;DRCSK8IGq5uXBqp`3-bpjx% z9X<~+*$RV_z!h4_ApTTmc2E4-janJlH{5#o(O!CI^`sG z3(%e%IIW89;TOKlsz8s{4R<2>e_ZM9QJq6Ubs23yy^hu|v9cE&BDh1<*k;{faeb^}aJM(CP0|i7wASb+ ztx7zaEvN`H*HTa^HxKgg);9C~`dud(2tx!LlcAWJ<=ePfHOK;7wrj8#58WZG_EnEE z*U?vc``_F~-0)SJtxDGGisMLAQ+vg$;;N%1YR)gU1w8ZJ6k0Khk>ODo_}jH~wdm&Z zb4nquOxa%ZM* zQ5Qn&AFshz=aj3h-~+w_TPFiWNG#wVj@Ry1{Ew_gYeXROAYoF&Y5jZP`)+@wcppRb zqf6{w5{usdQ-eH+Lw@O}3F0}qD%te1y5?o@A((vNkmSvR$@OCVtUH@``)#0|m@GIh z|8!?4JKnn97(hbif}tM~YZu2RRX%GVm)qeamLT&)TLP;Mhqk>z<>BQl4+w4-sPqfz zBbTCie)X)j#+UWDFGkQ}(38&1Q4gQpLs0h2unzV6Zt|GT|73*a-#jCbQnQDlaguM2 z-?5sJ>aSUk#Dxu;@|gcQsT6>R8W3`Fhl+XVE?w=scC2MyVPXZp1XzjIr|yo9ySo`?P2E zC#VGn^3nVAr0)nl{#Es<$uwveJZLhoZ2okZsS>G}>(*p?eyGM+t0O0s9b-cwOR&as zs9wRc$5#*+YV?5MiX1b7J2u{ms`*=F@{jxVWcx%PE)X>YNf(R;EG{_%j4SAHY&z|; z-by8qbq-Z;kzew%aUajJZHb_7t$=WhB^;sZH{3`2q-;5NLdE0kC8Q%O5%OvaFbcg# zHlSuN+N7qUNZcNneGSF{8kqeE_gz3=y3B%o9rA(WPI4bbCDSWuJY81~!}QCsxxB0g zd*ht5*sFSO7p^9-D5Hq4&^0GHTG*N8moMq`PClGhph2O;U6QQ?Z8#rhZqg@Cp^?L! zIlv+RJD8~3Y}K{1GP?L-7XDRiOKbaC6zA$)>rsIo%ByR%-I@Rw4DozEG8#n2Y$jCN zx8sob7{Tt*4AFmm+82&u*Gss5g87o3F)0oryNfnS!rRke$pcHUBI0Hzk=8CCbRVue^fMdd zUhh#X3n9>9h=)PCsluVZr6=KY^ayEKzn1;a2lKq(c>;0?u zzoB+qT1RZ^tcht=2=X*4$;i@zxs<74EsvcQtj`k=vv(cn4qKtfx%zhpDFnPCtJL93O`;ffObL|kUs$($iMJW z&8(#noA>LVGFN9oy}W=s40iy?wrekm|1M|?IBqfjrvQ5B&%@lCsO`ezBh=9$-w541 z;CnIQCEf*OmFu(k2@+179e+7OEP@B5Q5zW|u;GFr7?La1wEFy|{*thrSP8hI^YxCI z?PWeBxaveCgr~)4KK5q$?^G_VtKyM>*oIW22x>uz0uWup{x7)$JxhuhE~{X_1JA`8jkFSZ%|cQ7y3WN09@B=VlMV zufqDjInetMtoZ1s*lYr(V66gVNDeR8I7!AMJ&!H&pX%wY_=Je7ER%ebMebdDJ}J#4 zrbMV5EmE`F1htn@eay>0PA9>?0U71tiA8k>g?%$JYQ%vw|B|{8JXaNJn>K^_>bH=5 zTK}TGC=`VZ#K7$F8j2G}5FF%wL^YGyP->M*4-pt?S!^P7dU$tziijLvN4i%#`<2PL zk@RP%Pd&5nqMuRrYVOU$C78FnC@T)SGs{o2;G3~?o^Bg$@UxaOppOasGtelTHz)E3 z&5?Lun*v$n^M^7adHXYo+4;YD0-@eQFt)ir^MOJ|c9nAnOuw%XhGeD)((ZcaHo|w$ zI5}cJ67*&CAKb{V0p_p516Dc}yY28QgOP{(<0`-&b$MTmKEKvm!YmaBm6S1p&VJB_ zz3n%%{A1tO;!j25uP56Pg{h{4@SlTQV{m{16S|vi3_Xj#DC>}`vbN_e_5Ov_SeAu~ z(P;W6x`5(Hg%(U>HnMO&&;<-Tdq<}Sqt-fc)DdFcmzzZtUeP;#%2pXaEfsn@dCQSS zGqr(eg>JSl{Y1v|=5^lR-~L_R~mET8mN{+8t0c_R$K_18|H6=3^LR2hfJRZ1E zO@i?Ia-~-92!=S8BIMj}PGdjqO_f)pf_d$xQEKh2GxTWr0|3enWP|g!c+t)zJ^tf=jG62d9$KI0nbFoE`K$_AR2CcaAKe^03 zC0A{L<#8UWjfy@NR~R@+{nU z&n|x_{Hu5|7o=1}%tHfc+MRlOMTvvno{+u%?t`N(!twNXc;12x#cdJivlMmNdEFgJ z0VhJoT4auIc)ObXf{TPHMWNkq3n0|RBYpc7TUuDeP(@)wEMNtT9`qqn zLg1Z}LtNSv(ppWWrC`&U_CZ+3YLz~r16&-%Dwjw~jY?|zr3->98dE2i{D@T({F zW!K1o!{rPE&^oAAk~7RjHAZ0R%e;jCwJp|rDN@URHs|E5pdwWlL|~8Ax&qb?AGyZU zFTrALIUdY3KiO-^51N9?f-^dAh^n>rbQ|kT)wmwAQ|cih8pQRqbYEK8AXRXNhL;h6 z>H>m~D1+Dsdb_d+-$%U!MZbp1sF+1}5bdbHia#_!n_{0iRqBX|ZVNiHC76o>GeYmi zOoGOPO%jjM!b5MxWpf_*x|%89ZygWgeQh&*;w~kquzx~qwqg*LUedE=nF?<}sUeV7 zZRS4IMHtS~QYTBb6%v0yqVD6bOpvL6G^$RJ{i$piF>AGk1Z z*-qOH9F7{@U3Frp|B&SwyTzCYJ+@eoEG`U?#@3h4-Lm|FKFm;zC&Mh46uSybxw{?n z0L&XY%;kQMjUNwU09Rvbd6B@z_nsW^CIha?oF!9L7szL4$1%ug0qj^PX&nwKPGj+L%>l|Q<(5F-d#_-+`;Sr_E3GKNp z=5H{GQ8#Fmit>TU>CdiuU2s%0XGN0rRWi#NJ!yQ$&P3>N>Zh7tms+4~(ZY-562l}V za;BJj`E{~)S?P}Lg=!l_;rn4)uU90RyJ=HXdW*PNw)O7UT~JQ=bH@?nQ9On7Qu@2A zh%n9`9gq{8MNG9VGPLHHA_Zpi0oNiTff@B*uD zcTPfr`sQl(u;5H)g3id>1iGTTHpK<27Y89FVDsdv}OSXC~F`q$w1FG zSB)3viAWl`;-|2V@1}^;B)Qp=?%3_VCBgFI%-J(7LNY>X*Votm#c4nB&2i7gvRoLiifOCf=YD~H)z?`U9vMd7lgQa|Uw zy;@RZ!_AYBnxg8&g1*!T*zr^ zCyESaNpqH8Tf0?W?=u9f3L>&S7i0@{Mn#^lVqob1gg7`tEEbK<5;hPL#%zhutx{ym zBM854KFHnZ45bykD&?8G;*=B~B^@|IrTMeh)qdQv0O26=l*ST++tG;~Bw{biAt-6y z#ECUSZGYx9Dw^(iOt%KhUHls^B$))|AA7^NTO#H_LoLC+4?1+jS`MdmwDjh4Vm_cv zbS?+iB>luPifqtP?TSeLeeziug+~c8fMq=5OO8pmNVkFIuERPMXZL%C_i$M;>EQF4 zz5Np8O>W{ppw!Sm@4qpp<=uSx-ji{p@c8LaOLdnM;Vyq?HnA+CbtWFCy~Btud5$lp31>lLQwK zb7>`fVsWSlc|^%mhTGv(b(>akbV|u%&`OxG&woCHTqnl%sQ8o5i3YhzkJqC`I@&A5 z1Od}(uC6_#s=1a>nn|5h+{iu+b&8u()6iyy|b_>(FF^oCgtG3^pnz1)mNzP?^zxLii;D;Q6pdN zD5FT@B2E+Sh;`5U@o_uMKLnGd@U22z&+ARwJ9p=Ob@POrI>(X$sFb6K&ze%-h1W2(+B_ov?o_mKEGLH;#(DGEz|B zKhsXD?VHYy<{gia!O@b)JH!tk3_=qa^Ai zd`r-ru!#AK&f1)=;PU^97AJeYw_KEkt_U7}gJ{Yp;ez3KoOo7cYaa(26AVgXPfZWS zsGv+^ZMldv#GVhejFw^^P) zD%1O$72Y{{*U5ZTpH*#^o+sLNSV9P!TRR@?YR%Nl!^SakxmKwb43%=NxG#J^BI>DR zo8yfkfmK1n$$@Q(vpb8~V?slRXfESAUkcy&|&w>w`yEETAIT$ zK-8q-I&`d1SN2i$)d@a1ioVX;w<6t1;Z9I<7@MDu0}LA`9;~XRutx+J^Y;;uGzqH$ zYOvu62Ha-#dQCOvsuR%3xTJ5ts}JV#@j+c-m^zsT16#D(pSz@%Dh`YaN(Ch`c_iqg zH%N;^HhLsuK(?I7;cL9B@&t%vrYu?^c35?r@MkBxocbMRnAfvq;aG~S=scJgQW-m6#bigGcvo7W9s&abPXf+ivL;ws_2+sIvv}|3a0lT6jxcTUU1JhSmyObc|TVy z(ihv+%lAA4(FZ$d<=T4aJ8FzK(scPNrG$?cx#248k-JpG($eDxhiG+3X|@m#3A;s1 zzAwIv*EtZhfun~SZ%Kk@zobI$HX_2|Pn{(qtrr%-AJmG=U51la9ePjTkg5LftR$Kq z4E(~&(vuhgsv}Qy-6za(=M}|*d?rc~OozXUR8*HXodVU}l)U=A^ZxV=bstSG=W~y+ zv;Cnl5$1P#d$>jtMAl~XZfrF1K@s>xh(g%!G8b0)(0<7|u`qs5mgB6A7Yd80uj(a- zKaJ&$GuYW^vk8g)#r^EbBph}18OxA)62{?x8ok-6{d?H&d;i>T94Gre!LOXZ z5z{3UTQj+!Eo+6>@?Cgxl%VWLBAREMcVNogtk5#t-wH=pKBVhES{aoE_F7pPxjzw< zQi|rI3G__s={3$^nX%esLv!a|A)RqczUwVHcHm?Yaa+2q?S!Ah%K~qy$npVXsa;@MMV6A!{k8waujXxCO?sx5bhr3yK8#6!* zuHD`=7GA%7S6EXU;J0OFO|pV>d&HGJ3R5-MU?vC?)01oavDtG+*MILH)E;^Ibg}Xj z7<{Md`a^E13-!^s8u0!Ci6!@~TnON?Wb1N~_jEO|HLbk#Z!Tpg%ctP5Fe@XUM~Ovz zTjA7`@~~SYVsjQ^l}9$sZ*YH|hO7$|lYE4-G1pGEl4!O&V@X<)>|Sw2_b6VsbWMdd zbbe(*v~2)hI$fb|r$^7yeR~K#z+JdxADei^@iDvWadMOISIRP<8XUh#p=XgG(Jgyd z1Z}Ru<^o?czJLv3Tvl)a>WdTu)t2z$0AgK$5Eme~#wxV@P#H}-Lu>&|LdOUaKX)BV zCf7zi>nPy#FGdGX%u5cwf{*whAG~~?C|9re?d&0ZkB5sjiS!fU8SVr4G2r-3sNSiX z&e)2w!nc3uKH>2Rndn*(s-RyN=pWft0`mL`-lt}=(gAC8ONGF*${?ac*i8Tt-=#Li zr#w)jI%zl8lfU!#@fZe!=~uWXdR^!2=gGS+D?E1_ZRa3oiM?L|xkEAY(0mzwmq+aa z2a=3W^69aonav*=Y7>9ZW&ua*NiCf?m+J=^OF_E0VAan0@j}E^>?UwJf>xp-P(l^5 zheLUQ`!royeA*Z`RvgFTbTABwmnu&5S7tVCLUp8wMfxbLpl*!7=Qtz4L_mQCt^<;q zJx&kOuLOY>x{2)}24e5A>^}1}+gq51?$crAuFyJbmvYRfvwrh0E&paKBOPBV(6Q?v zg8r|St$lT_H~B4@KS|H|)bN<03EjYgCEs9#zkeH1qoD0v z#kw8i`0xH|WNv}Mxo5%ZpI4NJXyE&hX+{#4JSU3f=ML@_+WK9Je)3`8zLUIux6_~b zcE~h{ZDQ-*Ow9g$xKFe=8=?@nvA#0~mKL9(2d3JEOt>@xAEW~mWjxq;nCSgvq+>(|fg41#sLZMaBER}^eYyFJ ziIBLYcaUroP=4dyjb3)H^f7cTRHi1*gK86d1i3KNd*%FHrd1eDyHj}}D}(Vu!Xt*% zqFBI9Fbk35af14E%VRl3!%r{WSbp<3b_)vKv;*wA-(2pOf}zFadM6EiI}=OpnWiWCJe8{m3lTbS_rrkP-Zt<{gu+)UL5)XhG~vPE5KlB+I87(_oIO zN*cMZIovpV{D+{I**9~nL@g*thG~<;2*=6OL$f3Us8;k_=ah74DBl#U++k5RGLjd2iDu-2mHsJO%y zPwz{^vtVv}?FwB*y!7(FZkJwT8SBywTY%xYrM_*ICE%2z&`38(IR4HIT%*1H@fFW? zrzl11pNG@I4Pm5TB8GH`w$)xg_bfrhe)s8 z4dQ_D=Imx~nfK-!%M7@IMxDcwXaEo+kO;a8)Od+>+Peg~rwH(!&8L&toD@7x^}T)^ z;+adExR@V(+bMN@6(aT=2Ba@SQEtnb+p}F~q~3Z*-1)_263$4Y{`~DAAqz5u_5{@B ztJBFaz9DLIP4A1t=EAkqi(D1j1$YibPt&CCWO{@$iY^g=RF+&<96R53^fmU(Q)kv! zyM-a49vMY8fMNyoBN1b&-VFi~Z{Ud*i{o@^q13Rt?OT(R9*`xO;c~ zPv}DV_^4UaQo|3rVgb2mgc^MI_$`}H-$?8LT=H3>L{mdT5{DG^fc!+gnuO5l`CrMo z2iAAbcP*$dSU>ES+QBq!pUF^+{cJN_#`%n_!@T^}3o@2p8Zz5@sVai2bLA0$M`3K^QplAn3tS_aAlrm6F zrIf|B2cFv?<58yq0K5>55fyVe{TgM71wpuf6(s%7N(;VsS51nBhqE-x=QEZ?bLM0< z3)n)%+lUw#*wtR5+19CxJyB||B>uam{M~@Qvm&2@K)O2jY4?}rtg>cWw6SBL%XMzpZ? z^jCo&NAmNiLu!wm;YdTR_{|ar94{PeOe2@rm{E)s&xM>#HF|gSS(pY_<_HtUn8&P@ zCF!~PLpjwZBVC$sURUur=BccEGl`SOcC+E5WcMdqO8y-S5Q~e_4iI0Uzm1=Y+eKRL z!_D7Gi{OzFtG)WyRg7>xB6+N@M~d{_?csEUN-Q+LZruDb2tw2gmPPIi*Lk|Ap*>?m zBN3OIITz1GaphujjVncjhm!d zBx|*5aHr@|a(}RYgZcFca?7oWTFSp2CB(pEPG9qr#6ABDg*S}k;#T2v;KxU;_E8MK zUrK)dlSs8M0Yk9NC2QtG<{MvKaG*Dxla!Yr{BVku?sAX5ek2$-lm^)UJ!gyd$_=mM z_VfO<2PS=?_!duzBk>L4r1ndaatYs+m_c&PHvH&C5CQSwV) ztJD+KMK)Aiyi-W=Fj&830SmwARe;SQ28Cs)P8tloMcKn7HLK?gPOItg_=;I0F%-{3 z=x`XSl=ZJM`()9HaZoQ*Q_4_izR_!!!nNq$jVnNBR7DR33|_L=f{W5fJoo$fu+L#0 zwW_Kee9Uzs`R|(tA37-FB47v(p8Uc}RYOOVPp;7cYW(9`!Bdo;O&` z*&%$k>N$}NFDr{Nxhk@_1xqz&|5+)6Oe1h^TRpYSn^UL?vwxEi!RF;B1MWbP3BJ2r z+@1W4;WDi|SMJ$SUnOM7XN;XQcKbS6W{w{6#8`LlR4PP9{SZk`&MC2y&U4ADul=J{=u!&gykg-1`P^g`-{E8Ge5)2Up+S`Zg8X-OcQf3o#CZ1?*L^Ypg2 zxSNxu+GL7x?@e`XiH@Q^k!T5$Hx@TR(t=lylGV1a+6y9yYX|Yd(5W$|F5%$U?h)nB zTR&0-kisf;7eBU+kH*IPLLxQTLLxNlGlC@F=d3+RUL$!EiuDaqvzyge0`Ka8Pyzsh zA`6zWsUNgc4d=@z+4wBK-@)$1KS}gj)BNU(BMm6lVqlT2L`;|FYo^-3qo^kyfhcX< zysZopXLr$Gg{9r?^P z>|Yagg-^#4fmb9DV7sdf2Q{Q%F~!wdeswR8yE=|*NWTf1_7Ne<=Tk4ty=fL4R5W;i zzZc{Zx%c2c&rvTRgFaEkE>W~G`2C#q_|y$jsV^Rc+gXh3KAPmSI>PES!}DnoE4n=< zWe96P-gw9`LJOM`zv@i~DNGzb|5w%Ny-_`^yM)tV)xey7#^gA_^wg_J`-8yPyC3~RKH-h%=o z{n+j;3SdiX7qu!KmhrB9p$cAC`o!a@cO1w2Y?U0-?xE4@e14LOOS3}i_AULF6_5Gn zgnyQtJ*}eyIsiIs1`uakUH%H~%K^`4%c(CM=rw0xj2xR004A?!9DDxOUDF`!a4*KEci? zSNdanE?+8nx$&SuuJ|I@DVQsiO#HOA=zJEvy6+02D)q)|q(@Y0I7kk=2m|dh zw!96v0uomU)1$xf-efUFbra1kun6P$yU|k8D^^##tp^79x6#gU0frFJ@81Iu6-0rL zB#~1w(b(F1*J-xIwK^Mc@6A7C(;v=3@FJ(&NP}XH<1r6)+hfhWFgQQKUz`Nzd4b<(_LskdU2lkvK{+8o6P(y>)xx`w#oQvGxPFs z=J)Ke@*Fq12?P(mGMp|WI$DO!V95nYcBNB3IF?>S&(ofnF=&_d6W;>T3e_aGpVigx zMfmAp%ygQ&I`nPJk$IjwzIkgFyF?I;kiCB+6`4;!LExlOl#JwIluuzkr&3J=Nru}7 z+BvoU%_=Kz4X(M$?=m#5=lAB;@>ZpHy{%Q8MQH(pZIr5)LtCJM=&?z2>4HTlFXlGg zFIQUcY-Y=9h+*r0ypr|iBnPM|Rv#sw(9A1HVZUkd3}5wUva5yI5c zLd|rv9i|hY2yuy8YGkn{wl0SB_wMgF6qS?xspbZsD!p097pT5M*pB~r8Cz^IuP<&5 z*K8;8!Erf6vR(W7lvDMI@;Hsxxg9GGn<7%N7^M+L-Sta9$eh^&l4eMB+UI}B zRy!?Ih@3yJRXr*I#PTYd|%1*rtA9=17XaoI^9e{GwoVdTv9-&u?Cqw0;q`lspHOlbSGayb99!5SxO);NT1~hU z$udu0;ge^qE4t7J+MaHl`>+v}&awD9m9_u4Dsi-;WwTdmtQ3cf#iUWcBi| zBvmrs&Q~wFD6k%368!b$uY~2dh8wz?s?DnV7kCKVQ{N zssyUD(cjrehg_JhUkkc_ecDgw!{jk9klTZEit6UZx}MoR4Xozy+Cd7fqKU=05{Dwh z0N7ck&s4OQ{U#}@RY8{9#IPgucE!LBccMnNspmi8%Nte_)^4oHgW`%%lxA|Oj zv6|M%X4GY~9@kfT--qP>zPDUm)uxdxZw7fvv6-hF;nKX${+3aU@S+|Kq8r^vzrWLw zm9_kBJ=4m|V=2dMcfsBhK6(earZRJ7Xl%anZVM6PJV9+bWLzxs7P$e}P2v?4G&FJ-^q1S*+6e%Xj>YpMM`E2-S}%b{UT;08l`$zu-W97!TQa zZvY@=Kt|9IRWkrCEP-*;)@~>Qn?nY7NaTnC%UZ5-C6ZC*{jpHoe8z;%7tq&M5%#zc z(kXDLog3epB@&v`RYV^2Qt@zI{pn0?^s(4)k^M-cff?xF4aZZ1E;mkx>q=6#35u^1 z+3l;&d6AjfWW~29?nSqPsU%=yHVjf3|jrB8`ptrh4kv8iiI`U%uuT>nBo}3p@Ik9N$nm`KnIG{YLl|b#4eL!1+EVL}#;=wscrVJpm@_dcdbQ87N$ih_+F_$_-=>_SR?V4x-@A|>0YcQT5x-jP=I0YlREGKC+Q4EwV zKEwW&WinO#4Q3{na9M%x$n^;@-dHYH+)5COgoWCg4UoVaXM3;PDZJf)@#xXl9SIq* zfsUXbDQq!Qi5mzxFdx;9GLlvItniXcVF6!=aFe*1p;9@Yw44rj4$tp+6IaPge2QI; zUwt8;b1@Rw^-;p;m76r~ZBZ&y;dkI`ahJ_KN6KlNuF2t7&U`}W9AgE0VniK7#0es&vsXT0HZe+j9jYa`-Y=EZC^(Rfe8g%6evTk z!$X%oFIkeDYgTl-9{HjY+PlftlEv#L(qXBOq<&~JH!qs@Hh`K!LAJUWDOyvoVYhjE z2UMIo*Q2+?(cKuj4LH@A$htL_)2=h#iG|VXq?pE8NeIo2MAlszpFAQN8im-c+Nv*W zGK1l8Lgr=_v>6e5`}2Lp2MoKGO-$&6JjXpYaAU_#U^vn$`pd8f@i6DQ8WCHcC(~iJ z6x*XC+0>1&PO;HytvX_0zgIz)r-%*+VFJp2$PYXo{jhcn4-f=kfdd6Z%%UvqcK410 zUFJbp6`HXelTgB85J?6MkEa-o(UOK{3>_mZgqU_Pixh^hM#)~Dnc0ZNF&DmClBZk9 z5FqDChGSSOBpa|o00EU-$04{;@zPF$ny&fmRaL|PTRYs(Q1r^pqK4vpTbA+yZ34hT9F!4Dk0qWH&MB75Nf}fW@MJI-7;|RSbO1nB8%5mp zvWhuMw+Y6P+4AOAdfDFKV`X;9y=x;~XDKogRSAC{I{dv7zkBz}&az=6F5_BgG#zML zzz7aYbuS51sIFY;jZS7@cDQe~9R$q^x*)K2G1^5kp&%VsGeH?e7&A+BC;@!~1wen> z8f)fIlGF8D>ouA+1PsW?10x0udF|&#ZC(VbWcI8loS(vaQV8%t?aP80*gja%qCkw0 zht^BTRMho*J2S8MEPBFW*P0deSacI@j7-JhvO!FR8|*-kHWCE`{3TK`&wkBz5GA6)BMtu<7qOuCck zqd~!PeQtsmLs&_0@92{;t^M)(m4R+Iaxy!fY2!uq`ARQI24*(s2rE8{hD7C6APJ$L zwzFN&Dgfu1TW=28Mr*4cL@3@q+aM-m=+~Y7&xIF z^P_&HMNN5fZr4F|)K0b(bS3=qJ3Z-!#q}G3%%K<+iFnCY*8|VZVcL+!C`M{$P=;%3 z^Ophc;m*}nGd@;3aT!dkS#APM%No>VL`MYUqzD*Y#fw0n^zZ|J`NIm*dz9D*Wm#fc zHADI$$g-YT#1I0G2!E)pTogz=Is!C^BpDf*kU3xhcU8Yrc|Ue{MII+76mMW7^vD0( zxubqn?%sYXR)JF<`kc9k=m-Tq@79+ln}bo{NVQQ{XT>wU0l50x(1gO0=dGKb*QPZ& z0_9=k$V!s~T;|y6_|665Ya7m$N$n{V{8x zS}_mPd$GL(z|*rN!FoY3H1F+?2G#MNtWe~{nwDAhQBbs?lX!g#Kjt=NA~smc2S7D5 ziTOt>PzWv`5c>!ydmX7?)GISCFJxBX#TbW!KL=uSBuX!*r`BggXOcH)WffF zIOvf1!HEa#{rn12V8N97HhD)TH+f>P)B|&k5)mJy-{uYtQ3P44@wSiNsW%KL2WY|Z z@Hy5%llhhx_Y9NEeQXg<*BUeCK?dwVmOujGrIP>3Fe={_^D~E{HGyqhS#hx$pDIIN z+|EcoO7YH*WvNrY&?9(cf!2N8AOC|y2mpcV8x9QiK_>n=`d-*ziD~e2XU&n?KuoV_ zowLfJiQr9vdtSKev99!ego>xA+`}L;Z+)AV>~M>h(Fi7jU0wK35DqF=qx$@PMVIg{ zaUVzpJbha&ib-ejVSt#B_Wl09EXJ8a6Xm|qM*-_5>9YebZOpTw-UKwRt|`|IyPtgN zFP{Ta{Awf|Sggqnc9u}`pM2Drpn*sSwh63qhuHIeMy5w#GJ;>IaQr4vPUH`_U_JJa zx+w}sU|;VSE%RK=(rTIusrMt>DvLJuFS~!WBj`u=EI4N32(}2)@()8?&&Vo4KZK=} zVbc}ufUVW?p-ADYpOjeIPQchS8xx`LoCK4TS~(HHvgRc)WLd~@#!s-++s=es?kcHN zZY=?blKfNqKyYCPjGefhv9A@`Pz7M&&pK^89!BDdI-aOKQBmr(;Fbi9#%t478ZUk( zc{(FYyGYKvo#@;1znGN=VQDEEx%3pI{ZtVuiR6x96;zg5y(1UwJAZ^y5}tFDdU=M& z#CDG1!_@`$>iA3$PUB8_3&$M@i+zA0?1BxYxVdpVY1d!8qMxBzq$3`E8*8v>Xa26) zZ*Mo7+#(_r-oA2ZW$v;O|J*P>4Pf3WSx&VAiGLfI?S%O(<3#i*?YntOb@E2;veGtl zqA71ud2B#UdK9~vEj|(gtz!hpt3Fzpa9ckHG<6xlfr52LQ!^YEU1w%WAo5{Ii~%s` zG0To45yR~F56OCu68`B68R;{5FWOXyFqhef=fWQ!WMLaen`R;0OL6bS{(e~oc#Lmx zLo|-&`V%5GKD_i-Lb-VV(c-OEyK-kR4{{=-TisG1GG2O{?Me-cp$?!j8IiVqZa|3u z$N;?_*Ohrdc$Z?-8IT4~RB(Vovk{wh7=3j+cq==nj;JCaf070#+Y}0iru6G!OiA0` zlA}RTPzy{PF)+mA(g5FuNWT!I0)UU^M0G9s3ucr2w8Q@|pt?uVFw7Vt1Rxx@P=Iz4 zMMWYSFh&T74qqx$OB%p=uMoD+6mTLS&;Z!T02Mtc5OC^i2{45JySmb)Y+sVaP#Bvh z1ol9P!9N^n0YZgH5M;pZ;D9znWFO7R3Dl5C7>sgm^~O>l0|iRIHXucX)Kj1$FjiL} zw3Be_SM65?ceJl2U&c!|CFl}x;46}rId_otvf*&$M_f*dVtcFO?7uiKALot<)jCl` z*ak3XJy{nn_%!qF#r0hzi_2+87t@SsV{G)v>6Qb3#@*8d8GW|A5ctbKuhOQc zYIU)ySK^s&*=|d{3Z9DCxv*@a`NitW_eP&`GH^u4?oDAR2bj>)*WATw6?b~2r2VMf zG~@bw2ZA+^q~(EQY?p0lVu7L%?IM>h7}`0x0gDXi@#y|lh-|}R0}%lai2c1%$DcUx z#g%C+Xq(2tg@#jXG1_w~)OyD8OcCb-J~O40m2JA4e;MoIA!RihNz$F?z; zm2r41N{*uz0l*w2nJF>KFoK63b8+-{SqxS%^=puXcW;vBGITB7X+}X)7YDhOIeWv}835q* zZg1SAO@TnUeH75J+&3C+22*>S0L1YTs0A#_ouus8{DT@iEAWWN9`yUo`f}ap%m&MS z-hHmp4-b@+P03f!?Ba0@?hA%{Ke)7<+LZe+IWM=+wY7AY^768Vm+lbPfR>b&|pA zi`JBsXu-E!Rv;s0Y-}3}6Cgxp49EfeXk;+jE7#^2gWj;kbULUk!ysHJ;v7xYNiGH< zZ))^hf|&M*9i(92kfZq2{*^Bc zQ7g&!lfq<3rwtf6f%}_9zyT1%t)aAo@bR74X;3;C$si|0u<|puL?uX#EYbJP4auCvd6U0lyl001wUgYR3Y`~m~P(%sS-F~-I7~&z!+*&M@wWzHHe0kQBa2@@b zXwr>76DnyUR-f>!hvO|ci?WOL%;X_(8xiJ@q@qsr!0+=|sY@XRG*XLx_Q8SaPxC1aOJRF(lg2xGJnE$1a|~*cxd^cn zNA#Wv=l=)nr{L*{@EgpQN=uQ#^9mpCvyxseLOsWZ$W6|#Lk$j)^dUFsS>fB5qh7?O zW!g`x5$ND5?Ucqsq=YJRy?4xu&T3ZNA?H$nb$HSz^}3NQ5p5KbUm@z|@HVuDug^pC zvL6fJ{$BnpH@S8mYW!NCe!alr|0bFLwvW;m$fJp5`50#O!U zlFImH494#)NEv}#FaQ@X8MOX!tuk@7)dJCPCrK5Db!F1dvJy3ki)Oo$9g8uG{oAD;Wwj zKq4W*aTm~S!-fD1n~E_E_A8leqsP7OK~02vOrVGy5rhK z7oV$=hvcXBQQS^C8K7d3&m8!Pj&O0&oF4_Je+q^AQ7mwcf|TE0*AZ0bm`8AMqu>; z73#F?XIO>D=vaRWmWp`l^i6hAJa>w%3!}l0z>)*s=+6Zzw%g!9&P!j&A} zz?_}1wKAcKpyJ-Dw%C6w;tl&;K+$CKE1K`)1lGY<-3WYo4$nuouOB6b*t2@a)=B85 z$jK1HJ|r;1{NMPY;9YyZ?h_=2@vN8+gziJ8r}meOhGQ{qBD2%QihdLKTb6{ywX%@V zWSdsZ#{B@-l7c=5bumIhxt*dRs003BHISL}vSw>Ks{5;fccRQ10DwY*KFG%{a2T{Cz#oU?`9kFPKBYBKR4y@M1)16<3EQzd5%qnnhJeGXMh_1Z(v;`_p&^ zYN9QY5btZAv(>X82koR}>qB>V`NNEC4)^ZPKW5E{G;+*eevi)AMZ(Tf6t!mBRTK{3 z;C*UunoZ=unFe4RlL!Uv%tAk(-)9AF!gu#icCh>#kv9ZMvJwFSSURONusfS$Emx(H zF4~Eix?7zfj4@}q01N*nI0CbQgdG+yZVKWNTQ;UU;NcDo#Jz#YxC3%!Sh~-0Ec=S+{tysJOpP}fJX0l z)fj^S|M7OBnKGwX7NVaP$_#I_3<#*Q2}) z#Y$ybRUuqDHIkXLr15Ein=I7<96L6pzU4MSxG@7rcGr4+20i`r;J0SD>;^M5?EbL{P%?vh& z6^!ltCpB?>5_fXPE*W7O7(^^pjSU0lI+i;wL9^}f1m!{9f-AA zAp%DoE2ARbTl#~Qb!FJs!ksAF^?iH|9!a4+xrVD#bg?7|JRTsd0-{77m!7BTpzV2- zIHCUT?Lh$C5fiPFdPs$!0w9%)@q=Psc6Yl;Fbf$OkTU=v$#WnOZ9<3uh+jO<*#pJo z+SHY$Rc_hO_t9DLZ5&00k)};dwr8Ne_3ph@$b-p(haf^1bGg_y6tX^r8VeGO#~R@R zR0|DbP`+)|;w$?#*oV|lH((H?M)Qwkwq$2m*$J9ckSrJ?tGC@- z9=5y$PYrn!!W)1LIMix`>~L~;aWj1U4CATuF|24g-Tgj}$5>>YEHU&8O|@ z!=dl%Bef_hk+DB34y7bB1Rz%UPIzzLVNXEpcj$*l2(iQ74k)vDI{!30nbsYkmXXCw5{LH_UJ+J1|PTA^@*o1H~YY{DcEfS%rszUAI@MbJP&%kna%m@vc{w z^B@DMApx;vjy;kAUwW_m_9w+BkY6DQe16X-dqV3@UNwj`ax)#+d3cilKWL{|{U{4Y z9HoaT<~>#d{-#?%+SDNdje#56(Kn0v)1}{m=H;fZJts>JXVJI3`#yo*;d>cNM>S^^ zDwzwy|2~u9sXSE?^lwk zw21(~NsE}=!S6Si|NV$lZ_&SUvZ8{jkMpY(+1gBNOpL*x3s1rB@!sRG|1F>+9?!{c z$Woh#9xlpbI;$-Ax+sAbcMCG@LIGd~fGni&%zpjEpH*s~e9f(}A+`i>&g?IX(}Yuj zL#ES1U^|ah+%Dn!&u?b!*B$zNO&^S?zj4mdxE!p8v(Uw{odys}mmsPeyX0x5FPZrV z_`^Fp_Zv0(W*@^nCS+Z^8+*w?kl6Al~z~3p}l`MbI&bUI9tBJ zH~meBP~f8c@f~80`jS2vzl4C_wUE-#TKX%$PS~KPP;pf5XHSzgU?lz;tI`-Cc$CfE zv$zH0HBs_X-P0|&h^`ZiLFe{0AG#XGA@aCDbnl748#=!(Z0VHb&F{5X$nVtqE`$o5=s)7-0iXLY7BsTn>VE@lgP)Ej_>eYs^!+8YPu5)V@sw ziyJxxj=tm^X?ScL9bt5y%JHSCYdybxUxYc)i>1?TYf(Rf%_@Qn^yD|0Z*W0X2L3-u zkPR^+X&h*C)X3;-|7alLo|K)inG^AVD$p+0m|!elwnUX5KD%Gy?yEMJ$pG+qJ16oXM94X_YB z&vJvq99`VXE8=JN4k01)pa>aM(fkG?Ssv)wN!rE?l+iU-Ul4M*k?_<$E16@ycm7hS zMQ*Kg^Rz#L&~l-`z8XgdHM@^lr504*jNt`^1aev8ilC{6;w^w3aJz}DJ)S`Qt12S3 ztnolr{^uWQXbU!#PXf~)Ff+5rmiV5zR%Y?)C$jUAUJ6^X>y^52>=%mgc?_;(&|J}h zP$&>(KjO?mStxVB5mY$NsTl&OcQX@}n`w~|5ZYcU4a(OR{w=RuJfUPpqUQG8h7{m~ z(gi0w$K;b@1Wf=yL4y#;2n0rGGe3!vgkZ>o!Vo}=)l`yI1R^NVp&%fPfG}W)lrkrW zp)TlLjyDzho3qr>bDlfrS#WD$Pr!Fy>CnaU*XG$CZ*MYT zP9()ES|+{YYQL!yMP6DHiyTIf4e&NbQK|TdJW*o5xPk-$CdZh+)x3b=xNg6i49FgB zD;yd=xgz<19F{bX`~1fbx-hJmr=0|xx)OANQuT`GA#C9o;#EYyMW1^MMr0)At2Ji> zhelbe+SWzwEd5!uUa8<-OVrl%S&Z`iPq=E}ESOyIa0fi?@!44vy;z3YuM4u=ed+ecG4Gg74YtehuefG-N>wjc zWh7TGzhWMJrYHQd+BhN?f!#b%1Q0252udywb%|Al4y`J9ZE$F(w&+tEm9dG_deW$KTl6xov zkBsU1$9H;xZ(PRF)PwdAc|rsS-q^+w?S8K;`ddKYTO@L>CHXc^dcEySddkev-|>Zq zI9=C1(b@ClhrcePX|}ac>S4BJ+T>hCbgj@`nU+@RZj$q_?o4+MQ5ttZRqJEf&pV=9^o_cTe3U? zfd(NZ{J-oBFej%uHs~x1z)e4{-f;;)02ske1UKBSxG%?pg2smN45*-`X~foPGJ+`X z?t&5;a z08IctqjCrZzc6`h-hYkeo2g@6W-w?Ik$7(@Dc$T>$5&Q?taz*PJA@&S{0Y7C1X1 z8^H18ZS!zOPVi-tmx#G2m@sM}Vk;85j9sqeO;+G|IR-t7!bFc9(M8`4GQdS7_WU6s z%r=RtV}Q{67BTR<2`deaPp5oomVfm*g_`h*5quE*n6r5Fnr7Re-9A)wep`_7Xn}`) zVKeoTea`yO#n~8V`2uQt)ABZP-USE!{i6H~BiENueeBnn?nJgIb>1_AiucZ*`$m*s zI)@I;tB-^)K32P(2-T(doo}?B`W#i|kQ{+y4K5?D!eOa-Z&RX5&22fD`Q^cyd!S|Q zP$%XRaxjenl0j<4Q)l+#qEoVd&sMKDimNn%V}a+)`%KJ>a|Ia^aEp^Qzf z%OhKSh5K!~8NGg&`8c11C2}c&K!<*Z3qEw<>BrWUI{J@%#kMhT#E08E_es^=403O0SRa7}9dvT%r`1enNjG+P`3)4L!rGi;%1OgVQ&mj*m&o|8O^pt02jV_Rn_|&+E zX!O-85KIB9GikYy3KG2`$TfCoFk=dXr6eR8L6Sv`D!rp$P^aZCUI&6uSvhVaN#pMe zM!NbPv2hF^T{?SZTR2B8fGz=$BQgWmH%XKPL^pwo#9(5}giohm;r2F4iZ0ekrcj8R zMuGwP1Txpq0B{0Tl_5nA-+)O=7U@WA&65)hK~<8^6)Kr9grPElL^A>%2p~YiVuf_z znD{6G2zkUgdfR<)ONJ`$AKqJnFlI&p12aC%Fr~kJ=>P~H-goEqcW7Ot2841%VT(+* zFEQ_!9g7Vn2m`D*ooD* zvy^VbyPuLUk>2PY>s# z(h0{N-oIU$Yj+_q7(k;uqxK3Z?uz54LWKNoR!!59Ebc9Nt}t7z#^Sk>lrS_q@cfsh zC{e=l?T(hDMj!#>dTAZOiY#Lg?SZ8kml?!sE&a@XnMoYbpzBM&&zy9f7PZ=^J~aXp zIFE-JXmKwFLycx8%v9{i&%f`4MJ%te#|7u{nK>LbI6o zEF}5-v0cs~VP!>xnfXbukwDx~`LgUXhiRX*39%{|V!HRPG_{M8sOmU+3UePzCHAL& zKk(J!`Cm+b!dwbb4Bygs6a!<}Q*9b0J;7f;*U)9Sa8>=d%zGW@*=k%Tbrj{~L1wL~ zc}+`xwI92W*{C-P^eoEVo`aet3kQY3lD@W(IG%^pWWhiyxfwfyUxUNECyR-`!h~mR ze&ShCqf$f1+2hE4U#pV&HyQgscTrN}=W_#Jyfg3AZ6R_i`HHCc@ql>_$g`uEHvuCx zuNuCv3as+&=j;*$2HurVOvZMeSrEEQRs*J{!0!!m@Mex{cP-GB>|6b-aMQ%`>R+E1Z?_p0@WM%smbUZ znt7h=7=!T*YpDQ)?Q5d8esliooDm%SMP#mS5L*@90AdEZf#cI3N8-r8OZkn*O`lJO zy^|4YkEZcA07skUs4+1jfb3vQs~{PsYDRDa?Safj zpOy#s2X4eKYU#M5XX%~guIa$^hBp#Y+(8J&I*lhkd>&E4H7aLWW}$JFekCZO3R)Ir zHpFQOlerib&yxDs50eJP3&M2YJi$0>{_pxKr)%azQF!Y4NAeA@1atLit&J26o#{kV z=CXexB2F^@6gUaNXW8`uIuZrSs&co;pYG9Nk}LdN=&_8vjkjm9UQweLAD=i8>&*ng z61q6~HpW*m#+yS`UHe@3JTz#E5(zIeMp-gCY13w)%2#V$jnvQ1VtE6_N4vdPCX@og zE8(o z@M?t2{^vK@_C>bL+WL8I?0fU&f?QGLT;65Vz3X||fSI)&E zk&X+r9s#g|tScpo1V-7vd+cWrNqz30=jhDU?&l$XG|rF@kjH*+{}5!1pf6%=i=1|J z!zlCIkM(W9HbI12rLq7Y)kz<4Tj!pP4w=bjEeF3~l0ScnNv!sOao1nScS#i;P>Td9Nc=AV zpLz6bC0)_K4C@AVb!H4TV76-oN<@u<>liE#^g5}S>Dvc_!T;^h>QG2ZgcYn!ntQ9s zjoCxt0FvgZ0`O#;hZ~3BjLU1}alGdf*ZX+?q`WkJ4y72W%l+c-?u~T80_oY@ov$K^ zz(hjvr?u=nS5{QOS!%UYPtHbT4d2FP-M8N)f*{AVf&+hH6O`IyBd(#@-szRm)%`ax znX2=(pEWhHEVbVIu6%U-lO-?IQ~-ACe|w!Ma*0wXo&+py8oPzi_Vp{7$kK#_mB>}V zh!9uI%_NZ&U(UL$=#)mcPL<(ddPkxk{$$Kqs>PFw6!6bt(h7=Pln8&R=wNOHXjmjx zh?*M^2#*33pC81|7P09@R7Nv5P{rZPO#`nBSZ-)yKb;A+)Kd*M1l!QJKbCk$YIml| z-l{Q?pgRD6h7KL^37b)XxmQ6fw5!1ph{lBX$WTt_IxFQDyAeg4$MZHOh7Iy!0B^3@4hZsliGF4nTikqXt_d8Umo=+~LlbGUwruli+=tQ$p8^ z>|k4bEd?r29Whg`qe!lB+ZEGn=xBT4?wX{;Lbh2lRL)iB8fLzIuMd4YyB$bsbKE7x z&UxrwVwk{(5JLk&d5h|qlqD<*VL!x^q=*=k3n(CN1!KXESDPd|y?$heCEwj7Bq9QJ zwndYwA@A|A?(Iv(LW4_~+?uXCU{0k|uN6&I1mY*A-wCBJQx!w@BrXAC5I@8#6-rS1310)rRr3eqfIjcT1Xp~ z*FgMA8}J@%cC2*hD_|MH%Lo7r51MFvlKZ?$eN1mMQ9V{J_?1zLb~N-Ht0F|wa+Fit zT%v~yEI(awkDZs|8bI}d!3cBmZI9EcSWbL&RUR%GNC1?;vCLVPN~6r_X{Wr-Cg^c7 z>?8;vfP@$e^(-a+Zrdr@#u`d^>o~pG;G(&VDYmCuQ~9&YeYjlel)ZifU@ZJdOn8Mf z2a`Yn0R~|xK^bh(XWhKiIC+bP*M#rG?Q!T)QlbY)0Z!AyUosphRss3h`Q`NwZ^d!b z{bmvwey6ZHaabhAO!E9dlJ@OwnG%agOV~ZU_hbpej{v8$=zA@fQTd0^Lc&+;y6f9f&&%izq<;C zRzFA^>@b=*YgEFO*2Mee}#)(p=Z`+KA)R1=22tjm<54PaZshBV^+VX zn5k4k1}DdmFZ^dV$lDX`N^V)Hhg44FjZ=}gF5W7ZbqszHLs^m4bPBZP_t=oIyc<6s zz~d#gR-dawu5 zL=5sz!~(>@z|C7reL1o4wr^DSDOPdLc5JDCRxoX3(-`bgFZ~!dY>jN%o|on7s#Umb zC1kjE)Z-|vEPX!79?nxlrjS%r_D&o#Rr)8Mj@v75VQTUHUel$*;Kq2iJS) zwE_j!f`8wr_is!hqmx1|r7Z*2M>K5I3K<<)5bN1%w*o@+L&vUc>HJ#!h<`wa zXXS+2XsT_RSAUhWi8Kaph5)sQL3s9v7)^;_LWKjayf@>GS)4brf;vuTQ30^Q7zi*7 z!5JG^EJcGCT4#dzTVQn>%2(6ziOU$G>RVhq8kel^N5d3jP3aO4X}mYdAsEM zE4Sj(trSTGr^vFeWDi{pPiXN)mR~GXu4;;IlPFxuOU19Z1Lc+n3NN5CIKgg7^V3aQx?C^|T%fnB*x$aui*m zr3-Oj@dfbE4XvT6J>{rWsrBOIp4b!!mG%@S=#-ML3vKSQNsHN0vpU}MOHrjq-cRV` z#^nxE`Gc&AzN#zaqQ~%$1Km6^f1hxo6CwYFZswZjj!$DOs3l|ieaT|FyMVBD4+jx!NLawZ=M`4 zcPmNufrNz;r#xraZy}X(nhHp^U==F&)3%MuFMljQqqEj7jD*rl=wle8bVbS*bvUgh zwLe0jmy`ZN?1mlif(;yW|2ipsOzkjDYY+$wQWGe#@&X|g{$l#f21-unKm0_dZS)Xm z(pH?I3y*I7?6h5Vh&NHxYPaWk0^$WdACw(x1M-W`)Dj@*;3|x!sRaO|9Zwrd!Ba_Y zSbFq-8J)`@=pShi`hgp0KyGfCP0~QsR4#Y*Yulq^2adK_8cGb^xiy=-;wSyyK3yge z^XZ$^sPnVSngIxvaMopxqas#PY8dc8$Drv#;v5_0MijVt3nn(w=sQ;tRCvBzv_rJu zLT;yg``Q*|j+e27FfR?F6!4CuPm26Qs5#saQiC)5zO$S`(IZ^Uvwx8SAG;IsM&mCL z#Do^zsY6Z6C&HbNh97cut;;`{S~spl1!f?d1yY_CB=h<@e$c#_BHJkBl}nthjtz%n zSyRDLDG1a(@1!vnMf+_!blYyXyU5AeXwP{|wUk7iJJ`sIh-7AF0qAk>bicV^Dz+W0 zefYE`7Ha6Gm}V!9AAlC#P~a|+=TERdzrwAXoMYXB0*HON@yv-}|2Uwn4T@)CMdgK} zPLIm8N13zXh(y>p_!VE(gFpcT*3b3F5Css7+)h9<*SCgX8H53`TzXpF{u2lc=5g-K zSO%|^#-Bc2%Ogp2azXyC6bdK|B#>kYDI}5z(1a1EE`m^oFwirWG9p|4(l1D7e$LW# zd!}^8*{$R55yOyrm_(S<*daEsAG7*ZZXEqxFRk0;HN<=#+=p`j!I29nGOP?5JtkGd zA^^X{UM;(L-lq4#zpXeEt^A)GHLVw8(LT<*KU?-WN6)P2r`PPYP4Y7>GGEMc6Z&Ve zfasaRU&u{wp+O8c;_RQmn>hDNd>_OL6)bLJU((vEU0!n&Z^=)7tSq2vhJM*CvF zBvTG4D9YF3jIlQ09?@L7%mVpVd2Gf-Jvc@an)N7 zC7oFQD>PSg=OdGC)M4x6!M>STXm60-e9T8Ra6l{o6FKlheD9^K+HNEkAmktx-H;5$ zb1_g7*g!-BMNFk>Y&?E?7;r=Jj){}B0 zn1XtJeAZ(!b=b~dZP*bI?X-9I{PCN@0wT+DdISpdUnB)cfJ-fguN$ddx~Q~V@EFcq zH)Ek11bK#%1Oh+?L_!;Ly_L;dmS8}uyyO6qWP&0TWF(S0-|HOg7fY78LNOrw`qXo2 zl}^`@JZxlU#&fpX@AxDb;|3}ijQfk_>*a47+gBG|lRjuv5$)R=p@|rt zmA!Ylm_CeqA{rFiJJ$?+iBq+}UeRaIf(G&DBYBUNh|{|SfJ@{d7z+a_IjxQfxOxT^ zoljM{am*BXXDlab=DIpXG!Lh#jW&#_Qghxe<(v7@5E4yf7A9U>zUj73cV&#x$K5#HU0SI80$D z=`90hj=>C644~;5@gR;n4GvI$L4PoOhtUs%3uA1a5@b{Xz8hrTs-)P4DpkGaH-pOp z-yiyR=`HEb5&Sfq1p8J?Dfk*GMKwCO0{%~~2{)r@3^{zq_!nO{6U8Zu;q>9)T<$C3 zSDVh0z$$(s)t8vR<}s4H10~zkV?K)=c>p><#lIcnV|~8FM!N37GHMckrkLoc<1#h# zPpotE9gjq<0S`vjK*V~&v!&zW~wbfIT&fwJFe1#sQ+bwp-tw6@9sN2 zF9n#d#%2KRH+|I|!viRsUndane>2}LL3+trx4tPEa{ik*?A~r{O4TuFFl=J1nT6fW zzBo{f0Dui&07}64OaZE?3r8Ha<-9B+jByl;dJiXYxV5P1LC=~{h)2~q#Slw1( z0k}!)E#7LV74e%73Q5_ktxAND-m)2?AXwrum7np30(>)!VE4E6(1ZqyIfNQ(b)2zw zI3wLVCOB_O#y@;DB;FoJBvimatnRpzoE4CKF5TgipEUE+d{~5HUt<8)5YnNFfISM} zd5$n~x0od}&$u8z9sTwD7zl`9b)A3-)ye}embdo@wA ze!go~#A)C+Bu`~{wmpjl(nkvcNq+tTd%e55&2A)!L3;$SdvuQuL6yV5$`Rm{bwPFU zOnr3g-0$^LXa!gR(AW^^A=pHqT!8?!HNfvuKo2M&xB)-`C}6Z?Dm53^OoxO5kPDFp zITjq=(2j@6c^&`h2a*80!~nJ7-0`aGM7_VY1R8@RTo!x)LVz?z0RR^;2$Uy4L4*c; z1p^5j-tK211s6yq;xjD3AmVmMIzWm{ia7zAa$ta5O9XlLjd(^kvixWIMa%K;=tVw} z2wkRjmqF~Z;c8DYFYq+E`#sA|b#p9hXfEe6)2Mhz5`NrVFGH_{GY9PeHPzNtzO3#} z0X>=l$wE5AxK_ey=av{F1==Tr^HGDrA%U?m{4n~3Z>de;Ix*EA0A+i$%8A4=T8TMh zh81OCVOZpGe~E3U=PxR{5;~e}@;r$z76An{laYgQZ^5k0Q_heH6$wG#>c&SzFZj`l zm%Z0BTMB3*0ig{!k=b?HBQNZbx_yF!23wvF)Y!ljX&9izGmz0l|#8 z@ct7+pItb>;7A#Su!Ish=xZ+B z^lfP|KyDdQGjL^W0!MlcG5V^XHtWNlz2a}ZQ8Wq{KD#lwfcdc+(|F+D*-*AF(Fq1* z=J#DsHMEs(fb!bip{O?ljC$M$pZMLangie7tE9c=D?^W}-6$N!fgM0lDC)6K1_2;6D-K$lw1v35 zc#9H_7AJDWT$0L5hHLJ0Th)u_oB0jfUi=awl-Y(;2Wfwa;-ys57I=6%>JD4R~ zfnerW^UF?&@$N#BqCGf?M6 zzmr*U7ho9F)Z!nCsfhnC&oq4&ED*on%$VQaR2!-w+IoJ!Uf&*#!}UszlRHedX{R)F z-mtk0Nj?HH%eP0o{$+{5@0au9J3eQr9T(0lZ2to5Q`2{LFF;jYGBZESWfpqJ&9+;f zh=8dX3a$Uc{s&ji=+%IDBqb;_Nrai^iSnw@K$!qG@ueyn+JhzotjKwtf;Dnmnoohi z5S(Edq0PNSI`nlE$_cluelu3{LMBc{POYO_K9-Q`F_eKZxxzoWw4Z8zc2=^%_#4ky;tSxi51k*{OFj%@jj zk>y&^kkPCW97*NZSdsgP(CMU~1De}$0wTyU;=-Lp#cYb*w~vF_qw}Kkbln&+o#JL~ zdxT*Ca}Z$(cf|WiL6vU*p==j_Lu1Z}$ge6x6yPu--tf?-zX5pfy^X(Y; zqQz61zJ^>#tv6{hWz;JW(N&ALLQBh(sQ*UY`1@i?HBgYNxtxIJ_vW19#B2_Je`Ezx zb$9m8zNfcw`6<+%Js)WU0h6yvfaBl9o6es+y)(HxXgC=Q&1Ta=g^y*{D^D{NC?%n6 zjvuDNdPlRhdJ6GkrT=ZeQlT7!8rBHnZd?#Od43IjMXTR5+pXXB-GBbfMP*1zAcjPW z{+W$sMn!dY+vk_82fjtLEGJP}nHZO_Q6=w@$XQ8>`VDDR4P%hFEDFolS6Xdc?|ByM zg~xhZeK5@X9{a2^q*^fiqpi#}tm8*@C_={&!`6sZd4|AX+>9J!|CLnD2` z)jrsdoc(oe?UgR+MqVaFb=Q_$OAV@jn?Jrxnha(Dz!*c8RqAGCGNKrPz)9%0TBJDT zx?XTmYNNhpHS0VE}g-?JK{-@Onc%FZNTg@uHaC zMrbdf2!T@uL^e$CK93lOa#CRq$4z}>ce!SH7KXlB$#_HH&mjc zVqD&7#i)DVniUA@*39Q&+ju~H&cH|R&ro_&4RKUdGHCeVJQmfoo_{Om`@Ec78|m?R zF_)soq-d4T*NxjS?e=Wb@Q(Qbe?mfAzwu*d@J6;at?9!uo({!~r)lbFpeD7;k_oy4 zQCwG&&im_1Y&Eo#fR=B-)-=6;?D>lo@dlg}fU+fX=zn-1<0X~F8#hvB7+~#*$(Xvk znZlTKEgr08Dmk*wFyei%whW0l`# z!_CoqxE;oXjXHPXK-knvFD zzAlspN&?=)M{f{*B)6ppu`cmbTaaCLUAyQ6;WqN?VcXj;1QB z9dtJ~Q^9}%g9Zcr)x;A0fZZ>FVx#hjTzx}7Hz$}eFnwRy(QNa-j$gn{G3}QkOfDl&Xp(X+X z2oeYgY_dYC5fZ5eeJRupAN*?Ly-%p3LK?N%`uVPE|cn5!(t zjh^{vd@EY!2h`_&+-x6q2gCN}Hgz~1j>Lcr00P4Tzx-lDP4)ZIQckw})-xZgJj)}k z@@h5yesZMdgyRw}Qk_WF%%;0kzGsvUjl)K(+wW3p|9XK}%d{a4LqYs>6c)8c^YF3z ztGm!_nRK#t`IOTYO|X%OI(}_E+Fx;MvC;=_zd``eba*m!3=D`~$I46~6%+76h0WH% zS^ioO4ajtPPC)_%dNNcsG#NNS0b8!B921aZ%m9ijHUubGYQSA3b3zQr83O=+;0T9| za7k1I7{LUf!l1Oj%Yp6wHF&3x@?=zMN{|4F$pB9Dug0?S_U_M#$kWK6;k zDCuO8z3+7%2o~a45fH0jFBO+kE{4Q=E&V7b;2oUBz?(+T&Rm{{cWsS6qVUV+mBINH zj0Zz4;hVK|$PYh&XNfU`Y5Oa_SqYOlJG~kKkG(IBHZj8Y6tUU{1^bX+pIjlUgx9<0 z6(7Yi!eY9rsIWnfJT2iJ?5)A1Pjb(3{JhMQc)5t{204_BXE%N;W_ZE6-AkY}f~7T- zM5X2e6xn-@Mg=h@0p#+v^6#weQ0?pEn1;kBlm&IvV%aT&KZ>fz@uU^jO||%v`!zfc z&g)BGUq(HOp+P1Wnc~5jIj9T+hW_U7hqXuXDBh{G{D~t&kX1+Ijm6ZL7 z`Otn=h-al97;Yyeb#~}=vk5f>uDl4hz}--7D7a7^W3s9nZ#KTvkn*ksy!^D&mRpBV5zYT%*(EP`oky8Q(hfemh*k@ISwyB>++vz51g%M zba=@soij3Lgd=utgTEOoR3l{J#u_AfZ;AX;&r2B$1rPXF9T04MiEP&LF`g=!Og#Yn95}vln65)3Ji}2WK``zuf$j*WGfh>BE)A{l${>Kn)je zqwWfo%Ro2VG+Yu~K-&0HXy=a29#6VtUtOF=Lc<(``S*W_$Ws*<-G%V8~UQQeCiVLIMzE2(7aUAyvZz0Tp%x z2#^URM52iAr~(58P!~}E%>=Qidp}j8(P$tA;ikHxD?E2jHfOhh(a%DSPs=MctNp)| z;DSIfV9p580hsI{AkGZNhqsa5ti3%D=0s*0kkGTo`Bha$py0uRZUYzemJh5sS{}?? z4~pw;OXpWjR=>M?Z?1b){0=7^-WPox1k{MYA~F;vH50i{?vJmzfHJzK@|gl(mzkM_ z?-@r{zcA@=(3rgL`eIp6KVl2j%&&uoyVBcj2-Mc zkrpobNRX*(*kFh5;dzAo_cQeBuL=dhI~f8k>4Gw-gGrEJKwA!kjH(C(f*@pIqQ%gO ziUO(i{)v+=isVlpkkx ztB%>$o;o@@joWkyj%i;TsO14nc>pEq)l}1CEu7y}?@p0+oakxpke|as@CgTKkMH`> z{UD~MfB>on2)gD05Gp7#5{zWmAKHQxfdzs!=0N}v6QDu}RAIpp1s!8$$V(ENjR{N= zhycSSR3K!aFx82)4ZtGBmLngORe%h^0z9UtnWO!;Xma__)3BLGH^XiqG`gqrB<~p& zRxG_d5Gc8tE*f_9`hE{YR2@y|NL~#d!zv$P_dbX58<>7G@)S??InZZIgXb(2Vt1@N z8-ShcgR;R+Gigzzf@E$}>x0*-oaVCY&bl2~)v%4{4FU_JxH<_c@-#`n7NTH3zc24qQ;aWsV- z@P40hzv&q%>bs85(7<@BlVERildRavu#FOVZ#Vc5$6j@+g|bGI$CYN}Pib-?n_@_y zS?Y0M4f>eH1gkLR>vTy%h8gm(GgzK5n!rUOSs7DCruLQnGc`(h{4A2%31N3U{AOPG zG|+2$1*kK&1^h?TkfnBPFX*M~fZ{Bk_KFY+pn#U_S01IE$-+$%G?p*tWM*75oahpO zaYQq`elifF1APn@@t3EnUQZk}pl1d(TaTvgY+wp37m2F>)+fByZ2ps46#~VLwjap< zc301JFx_sQu+$6jX;3u&T4V~I%#HJ@r)a(>2SGAYcGL%%ln%~A`HHlDA?bO(a)F)B z4~@<8IwH}oEC9v)_2SuhzECb>0fFXH$)P25)?R3xLFan_sl|XG1ZYYeGx=UsfNiDE z>~MIN__9<{@dmbERc9G-`Hc1Cok0g{rTmKRc{U@NS{De1bUvYi{MNk%K2H3FS^rc3Mf1n2Ysbja~t;oqMhN9~)8S-n(Lx zR_cjW?Hzu>+nZ>{^7{W{XiZ1B3bc6&1{HaQ;xDhz#S8nH%?D@nLpAy$&8)~85WbGk$j8v`I7 zt&I5ecWR6$7MX$4XIIiu>eQ`kRV$g0viLU)?dH(c~agFX4kuzqCNT3&N-4X?zj}(ln$VX zSu36>{>`ZC!v4uT#ZEIvpE#cFAGr$Hpb<&yly4rn%@BVyl(Mvw=AF14OC<=wh8DJ& z*;!9wLiJ&JO(}Y;Sz%$hfR)|~XYlO-Z=z5*3RY)69oJ^Phhdz@OX*=R-(3@@h5J$1 zEjz>wZ4A(N*3*T*`IZ1@kdA;ab})OQ1p*UnBJ8sYG@u#i86KVU~l(iXN(nu)f6 zQ>swImR-bpMe9P`1pf7OYb>_3uCZpM-vN)Qbc``a8?)S&m?W?iHn|Q6vkO_S*clC= z{QkYE1HW^LoRIIp@yQ4n3D-%>O_0*(@p>#S=aL~(XXTsqG5&kII`REy_=W$VnDu`O z{Y|KCVRXCp;P42+XxX-Rb)+G_CH7O0v2;VD_;+wKwV;$P&@`I3hp%1)t|{fQt>O=akKs$zvz^6+J_0{;0G3EDV9x0l4 z2Q6Fv?)#Fa{Lov=b?iw_-ym#o^oCGz(>g0ue=E@cu+?AUE{?nII(_vm_mi=?rh@F9 z3INZYF#IN|kOVOV2+UB$0iZpbB+_4_o*S?6Sn}VHG0uIc2E4f-RRG>Y~C<#ca)KUH3Sw58acIDG)iI5PMEn&ullfO?*!nYQ5+VV zSB>jqY|z7JD*dh&=Si6UsIvAKjAfFZ$Fv3@ffEEEioOQ4{ps8myW_03bMQO=lBC2$ z1Q1rii7wRY@eo)Aap5qpw7tg(K%EM|9u83Fvnzzhuc0`Y)TG!peLckaxZE2)061H9 z!IZ(KZ<$J!Bf}uc^6;MQtcMH$CgCqq{RSJ`T&J>*Z2}`#gzmgj>JkE$thXK!KSGGO z;R>X+oBWRyF9iAvFh)bE7z;XbgC0I#vy40Rr;zRh48X93Z|dPczGNL@w6JHVNP~p& zaiTE+T1uG}5M9|@AF~4r1acqUQvVvwi;WlYNFEt^fhf*eDv9 z6J%g@2oVAixJ2p(+FJV;Yw=Dx@9}7N| zF)x?D-~IT`8s!zD)Y|^BK!HfuYTo>1n&64MbPu=6kX?+%zB#oG${tj=(k?BRf223F zMhiICBzVtgBEf7Ee_5_w5EQA=4Z2B4Zv{e_Mq2{ZAtnU?d)?#I{x$T2^OlzI zMFE=*)Njiac|qZ>hpu7(cKA&O6nXCUxAJ8^MiM^ESy?#w#a?E6erdD8Hw&l4_e1>f z^P{I%t9-UUR!a`3GX@R5ylOvR^BEo^>-+9&6wwEmboZY>z+fDxD*X44rV;+35NQUy z+CsdxONV(~<*vQH(`$D9OWTru`^4bJ5%=mG5a^`tEqF>jJ}FXghDm$~&6dP1B5i~) z0WqQj3;Y$~3GzaStV`3NU?X` zIeVU4D<_u1(nZNfsaXJV&8>OPsItDZzd!3b#R9(Fc@}7l9g129xNUf>%!_wZ$Eohe znZ2vNsW^nZCJC5+8Cq!|z3bE^>ZA;bFaxlSktDiDq5Ljx7xuoI@Xk1FyC zn@&9uyi!FAT}u)Uzp~Xk$V%S9ByOPL>I8+%Bt&uXfA)W~ZPF z;2;RqvjZHeXG;7$pAJXi9VC#-S(!wuO0=9FvJL^lf=o3h)lq(5!99=7U9HZ+60Je& z%eG)rNRf&FI*SLmOmqJDf3KOYmLT&MZ#B|EHd~gzRd&y>We75CGuoJzFIuTq!7_~| zICTcW0>}?yTIyirC@iXk zyC-r}Se^B&V3Z&&4Htz(upd~}_xM(PJ@5^+v#;gq4qrSuX-mFCmv#3#&Oyy+YEL!p zW?p;ak>`*ipdbgFTi*DXJQBnRqd^t{uc%-UQ}(zu2*$kOznT~KBLJAv3!6jo%$~wC zJckYtZ6P!m0l>ZX-WXJ;iUjZe*=xEUl(RkcN&ZLPqF#J07q#8xwflPQ+3!QW41L%T z2SCAt1PsfbB%DBExNj^BE&F1|vlk|OKitX%6{v^zxd-p*FMeHIw=9E9@YNOML}7h; z%SDayUThE5@{fioB>X*S)PBW)RZwxMF#cWV7OcaF2L%5pIG?%6diQY@Dypj9m+r76@JC4Xj`OiytOj!75(nMB znQ$PcBxPtu&66=7KkMj(ugH_)?gEOfPP|+10DnfB^$iVI_&p+w)M5F;xG(~Z3Ov79 zAhg%31xmpDAb{Wnz6@8;&o zr;I5zT4MO)Q*x$2?ZWIG_1~S?fz2p>Vr+{z21BxoOkKCn#z_doye0t@5AI(OgJ4H` zCOv3!LY3nC^~~?oS^@84qH$t)W%+2k+MvAY{gwZA56Mt0{IsqFejIv z&6CI}y^epf-_Q{{IwqJh(jSLuN}1uP`^Z=L=c2qs?d#Lt$yCa}^Lk9aomu)jnbr4D z^`wt(T-nM-;q%pN#S=WD0g|qX%kl*cH?vpgVe$AU7WhV~|CgISr={2`Q;0B%dzR^-4#-#Im zx@cyYz1kO)y+{^`B)i#9k7{291pXDgkJHRV?FgBKoA}yZCOdhG!z-s%f}KVQUsr5o zs^Rw>?ksA~26LBGnnuBSvvihw`yFy$W@1wtA9=N@*^07OFT*&(EqnA&Bg)0ZHAei9 zCRvf2Nh}Q5b(lkfJ56)yy6&Zdh2QsBmDwUoP%Hyl8$xod&&?;a2Qx;bnV@W8i3zXL zt*C<_Xr4+`AH3ab%yR}HNk9Um*R!f1DBk!!u&3j{j1ss0araa@ijlTszFGCJLy&Pa zCW8rmYeQC@dDce$68oPa*U4me`Fdhe|D(?*#8p#(Zzopb0>|+A_`+NePFJIrENaU}CYn>(Durw?SuI>PmL|9cQ%G4><+~05BI(FGeSLO?TU89y{}HbJV)oNY8?#W3tOm=_DjHbURRa zau0fm&n3Jz^yvC(gVCHP3b_BIaY(MN5|wL?16(}oswh5+-BEKZSj<@vCuS2?gw|^n zizjF?f#s}O%KQjWY#o#`H|`l3u8uG-#8NgiNOKK6y&`u|)3B1-_Z3zzdQ6;AAwt4_W(zUa6XU>IZ-m0Bi4wzEbP$q_Z4Z#_yoOW!aV$(oNqB9^Et zUF3Ty?bb9?2n#L{?^jaDv-P9L!IUkXP2t@x0@pgwX(NH$sZNaT-`W?iVBAxUX`1-T zF*&x5j{jgJTx%(D)>CaAlml3JnCQO&3?EbWeHMVENwRQZ11Yv=!Qu(=o%zH!l~YJbU!bm2WvYx_MFuDzdn9)7SnuLJQMN zRN)jx-2R2e`)CQi)>#}clQV9&oqG_l)^4NsHS(_t$yOyA3%=!p3>*o7VH6|SgmHeP zu?MKiO%@!{M|hhsDP3DXoQ}PMx^$u;w7>Cyw~Rv?y5M|vWcSXDXw3rSXv=o~P?7#VDo=h#8y(c-K$M$H~aKqSYY zJd9fJ+wK|x%#=&U9W`x|jzyAcr56PB#qv4&N!3<2b$gz5b6^YraYFT-pr67senIxGQ}9)E3mNof_?EK)Ndkw+ z$V0`xlrU*~9qa9LAzjX>o%O}jgtO@3WUTN@EJmM%w7q9Zz1`1tRs)i`NZ69!jbS|x z0z?|H9K9qaG~Ms0n^RK|Uwt%lWe2>9)`4a6-Tp3se$U(%WXbq`WHDkbHVHvz#0__} zWOOwiIE+)bc4Vx$6FELr7d634w5$$iRdWO{{uKl(aFI)Uhs`6JTh<@SI2Ip~8wNq@ zrmRxv`akm#;%{p)wa!>p^Hc0QEMc3^qPKqOXca=T5ye^q{780iVuB)t6umLzo}q$B zB^FdM7@hZdg#o-E2x1#)~(0d9G*5-=SExI*u%>UZn>r2h1q;%E-4(9l3Y-^5eE^n*d zk_mSzi!HV{-AiZ?jjo7C3CASBQ;}FgVowPLJ2K27;}yMXsf5Q;Vf_1^bacfTLMD_c z->uPLapI=yTPfn8S;8@}Aa_O!JAu4v&uF$t15ch^m&A@iZ{0!$#1C9VU7pv#0%Yf- zfm{%6^P{Im+KbJ^&!~bL98{y%tLmU}O+^1Y2zwaq76?Ml&>#_`xy|pyl?SP|?}xx( zQ=qFkNPwDr#p+<0t*3BNtjl{Yy$v6^U$#{vw@MhSYqBxX9p_OfiE|cxX~71a_`0? zQwEE>+0UyCAz_Fhl=IX=-`m}z>hL1p+A^&BG&UvROR3zwTA3mG6W7_NfDMVRiOh3C zRDETD^Z%T_Av{nWN#e@`H+q)!r6^Jtt3Tpk;4*51aDE^0YayjdWn@RN5zHdA-#BZP zz`mzMmNLhrX#Kx=gI$^2;Yke`kllqIpM&F#1C<=1E>h=ma1k{j$cgcQ8^csHR5A92 z+K;nl3wV!@lKyh`ER)2%>&@RTt_r=jEtgNm|6atN4h#XWm$0g}QvF}fO-Br4oDqS5 zGTrsrRD}|(Ux;o_x9i5gi7hG-9Y4gzWV-l%&OB~1Fs`78xU>~FyJ@l9dTP9iLv~n* znnJ`JG8-f_@3ii`C!5zdJCfiyO3_cy5toG0S7SE!6?R{1jP^&zUBBt{HSIIIt=&)z zZhKSBBTb!Xb;pz?`DCqb@_VAGrR;t@$;rsdUoImCb)URFNYid}BqbJ+?=Px$4|WI- zsAb9(U)ta5q%>;za9QQ>vRWwv3a|AeD#uRXCFECEBrlkE5NulmIEFyLXI2kKi6`nx zmsr9%q!ub3`G_)00SM>@&YQ{mF5`su`}dDDJLKaR;JyLvSrPLX;HXMO2t zS#Q**d-2Y%5>wdXi?snl9U-9we;4=8(8}{(I9)Z+#!hjIDGj!14lhi)sQ_en@i98# z>HL((S8T8Ga%ruyDFl7QKJG{&O7Y{+ z7xY390PDtys&6`T!~hRrE1P!jB$kU>NPNnB5-6NIkEpd?Icq{`T#=(5C#6WFaplvG z)HCFnzg}RDa%VZay^Qw`%eh$LW&Os~z9+1Ou+D%^&ha3W_(o{D#2_wVF?@ z=_M41F;4zPybLlmGn*U=_Uvd&57mYu@_i_O@mJ=Zz}&v;mK}avWH@4V=K83X!3;47 zmn7VjxXz^Kh1+ATrmz+@|87UuDfW1Lg*>a>U_e|)?W9?DNc;87d001FDM2Kjt;soe zcDmf!EubW|qmr1u)zqa~Amuan62(Tcyev!HMEkVPf9c>&fcUB%C2D5?0L!Kh7%)51 zJJZi;&BRVkpE|)NE51gWcm({bU#>5sF=y*|=KwxNdsZ0MbrnJT&z@TEc#P`QgOSjx z3i3v{ThOj}5k3?C4PQ)R=v&y;geN}4DVA$coYwVgm4UE!Dbo#d08rnAtTZxHQ(EWp zXLO)zj*m<~gd=L8QAB*Lgo0EDd!J^8UMddtflCqvQ^taADsu3P`ApkN2NT4gR1ZNYB8Wp`Eze%|bj&pyOjy z&|#IAa+zL1J83cOjME^8Ri%1)4N91TjB~2ssaqO+5DhIa$-X&$ng_#Yo!}X2w+k!G zMAv959jVktn6p$ERd&)=$5=ZETA$n#hC`4sW{iBb=OAhK9~rg`kvE>V#oP>H6IMRzb(4JO_O zQxd=}3SvXZi`x%0-`n+pD$DqtH-#I{Hy%rDiG4M}%otyKwWzkHbxukX%}V@+%;_rj z*INe&etwsNjS7DABZ~P_-MX-!BQ2o>QR41KV8NIG3Xs%tDfRoGXLaeLXluXd%L>{k zw5h8W))T6{6m~jx2?+N*HlsH6Q)qF`?L3f3gN2fa4VT@_fSJ81UI#Obx|1c}l@gy=V!asC z*l6r1K$K@YxUCYbZO+^4;r4nhE~cakgUEP{eOujLF3L}j>e?!LiQ}5 zIB$;*Ll0t%ppJ6!+$1)L*q16RCO$kb$?HDqoq9G6PEjIIlGCS zJ8M%S5E6q*3#Rm_-_=bma_Tiw(f!`EORpYKFi&@b!hy^?Z{z}BBlvQ5UqU27WK3)? zVjqL{&0)GX5b(sg?Ojn#7mq(HNYokt6(A4@n{MbylePz|&2ex1#m7=1z#l#F#7$G4 zQ)nlO$3dK^^?;n-LTh(NNCp(#H2OSkXxRJ^8X?WwIh;KrD>mk@1&F}enu2@r3y=%} zib2;O>iSIB>erShBwq>%6F>cAL7Q2ZH{rgypzN~QTBS>V&8G6A)Ue|UK^?4EQBze* zv7P!6@^(7dlgszXQGTpWdgE^&d%3DFGFlKF0$ro_ECVzu`6L)j3Mw^s=~{mac*8gX zuOYK&oh>+d(`x`PL;{k`9a@~MT47!GRThVNJa-DmWO4wxTtZSB2IWuaBA}ge|pS?GkFVw)EX!#N*&m`9?$FhB3>=;%sCw z2o`egj-=VTHM;v!qpc13g?xK3v6eg2D6YqFwi!s{maglyGaEJU*J}I9up16$i_Eq$ zj{Cp$yEwUJC2NO9zJXRh?8tfyhqUr=Tgp_36}eap^JQq}SBU6&_B>n7zYnGAd_`(I zapXg)o*lp9J+TV2F)1jaG+#ne=02ftWcLlTlOES2wbhbOSh2R~PH&M`nq3W2fY-|q zw|v6vB-2{2%|ik+ zckbpIq%5$#$Z!(AI*)xu-+TI=mYO=LW1pfHY!bS0Jqh{uxXr#*`<0`CH6Tr3NC})zrGX_kiQODkT?Go6e-x`rrOB~o zitOzTltNg}Y35_c(|beb*Kfp~h-7EXuiv`OlyN$`cUnRO?dOX?ZAP^!4UfV=w^DEz ztSWJpEg1}Q-ri_(Ll5|jZ#C=>W&Uh{x6y_yOSDrBSh@WB*fOicwc@bDaXbmY0|wbh znD-Q2Q$hG{Sv$ayqt`|yCYkrBRLCxzVNT+mrrQMzqlGB6@g;|pH2ZFjaY!FpovI$U z4FJFH;vUkv{iU-g^_t2!+)s*~%hyl{y~Q&i0hlR31P)Msd<22H93oR$m;!#+Tz9M? zwi*Aq_nIqD^W<(!4Uq*@gWxzI);f#}2GMX=<=RQ>-Xc-EzdO3`C>^*7lN(E3^SiJv z5kc~J=6<5$Uf_)(aaLT^*l#KFB@_1g2zX*A>fqN~p3lO5EXS~GaGs`_OKTIqlj`(Q ztx?GDYOj4Eb<2>kfL0SSBoPDvfKp&X&YFNr(t7*+ey-Yr$x1Pa4iRQE+M{;9rB-HB z087&`^(np&h3Tj&j4)PB=WC&YyOytM?t8-L`BVat7mD%K%&@TYsGyat;zSGJN-YS0 zAzrXY+Vixk+tla{tlOz;c?dt`I_s?>642ku%sQ>;Ak`}>Nad#3*BG~E3C5951bSEV zv>aC~v;`xWeMf(+iY&c8PRgrs*?BR?#rU`|VwNffH&C@M(O~LpIAzYg9Y((<18@xd zCFX-8^X)3KL<1}@O{dV-n-R`ogGQVM^2N>E=GW~2yuHOEYKkW~9MAjf1DYNVy@S#) zISyZv>ali`=c+K{3`| z{FucQN|chI+)(keed;SWplh-p&4Rrp2)Fif_uT39jFrimB!)t#B{K*T<=o0gf_=G4 zcBeV71d5GI?6=IB70xh5Hd)>?Vqn+H)ayg)^;4C=pb&ucROLbAty1V)gT?8VX_q_Y z)U?MHZfJZz=5bBTKoo*~&jdl3WqbVjn>7Qu+8R#rS1#W%5QlBLL{m$kR6=Fd-e1@c z;S_Rj@mX=7CtK`kVUbG~F`M$f5lGjOfjJ`Sdux8Fs3q|`3~S5q-VMImsySYS+@l%- z>!c}W@N0Gk-BpoCQo2TI6bp|;v;8)>-Nt7%Bg4&H3 zeEuA-J1vuLW1BI{@1mfE`3PbWDj+zScMBUr%P8UKoXV3!!%1BLaElEge|3rV1zumE zsj{$#$qXYpRZqw_;Sla_3Wyiz$k7U;Q{?iZIfqNtD?`=VLxm*(<;Qo)j=}<0;11Z0 z8s=~10xHbl3LLe;jZeuw#37>^-Bj9Hw~> z!oNXC%Bx2u*xra)e3>rJvKc5Hc7+WR@Ejgt0l@fM+sl(FXeV-lg=trp?7$xl0}O}B z;MsZv!0S7h6kY$uRRxO@@IH9J>SfhuG5+KZQgJWxq2IsZ8Fz?6)F>KQ7kJ49d!N{X zlPV>|TCEpUflJCUnsORlzG<3DQ{H()W+DJJU?70&`08tay&Ic;>wtH1=k|~?oTuqA z9Ma)uRrL7j*C6Y~{HYCC32){sH^3=Et|xf23cuL^I3p&b;1Qmwq-l!Z?oFN?Xs;9X z&v45RGx_N%yVa}k?}drHU_4J^V1GwvDBYn;8jVuzyz>P3RUY59Z(mVnkob{1gXWoE zUmwU(QU3!5K%W`8GujZDb9kiD4a{AuL#=O93O+J6(w7>&Hg!byaI(>NX_A;w8E7JB zRZf~{sj_xI@gH{ec`}NN2JC3_l56C!BHEC7fyQ`W4O*^i$U1sO^2IYY7W~sMj(QuWS zyFpMaq=2#W#mZZbytA|CFXQTAT5`-wE90OR zf&!r9a?3PJIW+$C#P6B@rcCGC9kP7}WhS0c7bvmy{hg5MBf*@lM%Lr4S9AU#vk0u1 z8dq_=hWaJ+Xt}W$q4%eQ{&H(m#2Q3oQQViS^qi5umqI?4IYy_lqMMM#T>a+QUSG|S zCG=j-ybE&v^oB zr*r@l6HT2(D{y*?2|YnrR19ZTr)WG$Xh(st?2VA55S>Az={5o0rt$WM@-$#{6c;jSS0BW1n=YnH)=W zHw>d_&sNXY263(TaKS|_LT{Cx`r?lRz)ple^JOXx6ZL)dAksnNagOYelV`5O9*v!B ztpE3|1cCn~3P+(==s_$3s15Vo0*-wcW_xVvg%-nss1<|A#;rb5f9C}zFna~WOuoOt zw6c#d7w0W~5Dh_*GXQ)Nyz8bWDFte(ay;G}&qAn6-0MFK?;?#{lERN?0Uq2u#IlPI zy997vCOlUQ-)ZI5K@RPCIi4>@qg7Jh->*@7Q~Y|JM%ma+ccpfAz0)DS*^b6Om1xyx z?O<|<4gd%Mgy|47AnK5z1p$P0R&RDny-Gei>VVOqgbQdkk_Z75RT!GfvRE@Qkz%@F z60l)7kf|t22T*DfhU;9YLfw69L~iShv7gcb5O1StD?e{@robC~08v1$zw;qPlId3P za3G=0)DagR1=A74Rj)&g-~ttE4><0($eB4Nj!X?{fb2lXk2ZuDGBr>m(g_AZCLDL& zktIf(xmn@Fm;jCHP=_;(XrW~t3Y5B@-{+NSuWO3y%j%hrohs=8Vu!w5@6sBb^Y+^U z?Gf{UsE2oa(e!;(OC}&HMA+8eGi!e^teUx+3#5ojc~?MjbxXA~9)Hq;0K( zlo!+Lr&`R|Pa+j}v|d07tk5WDY&=D(aH;vlYp7Wtbi#*9_am?d467^^UDSMp0RaF> z!6~x{sjD}k2uh7_KsH31j0@79`qszDIOBzrVPRSdxQo8dGE2~lr9cp7TK8}fQsO{( z2*M1tjW=FUOxkNQr4~YvtAp`uB*@TV4^RdGT{AGff;Z2jLz7rJ|Hw&J9?cE&@?R)G zo>>992$`>br<+*PvQjFTfLD4sCQsccuU)W9!|JK~gb?d?%N=7cHD_BQ4-WUk)`SHl zj+>iANa#7zhV0*{{=4iBtDjM=bCBIJN`DHlmPwO+!(Mkt%Z| z`nU60a03XtXHs?LCL(Teb$8`n-qDwURlW;lW43=3rJ8uy(^$)6XDtwMmb~}FdcRiUAkroO|}O=EsOkKr?)dZK3whlgl153N>y%RU+j$}`Tm)HpW$VtI6KpS zs9VB7Bn8e80LdBl-^hRnz4kQ65X|nvK0<=X>v+j3wFV_g*M5i0M?OnsERAXDrI#sH zm{>7LTnrEh0{jRf$q;wb?_8;M+E6?xl% zYRWX-f8U0}T4DU*Vtmqf2-8?rpA`*G!|cFqVFHQP(|JTrXG0CXbW0trM`HYI9ufFa zJM`@8zKoJuW|1UT`QI%Vuj$ZqAD2adOj!aZowZWv*_4YChZ!U1d@j3QjJmmfS0qr) zVutAk?wDob)bfJi$sgIB_0s@h5r7#&V$do?XevFoN#e|7YtY$jDuQ|J!_b!FYj>)J`m(6(Geg$ z&TToUS6X7=7#B4V2iqZ2g61OKr|NK6g-wD?XCu1>nA9rPE@j?*-gmZyhcjcX0~Ad5 z2fiJ4BC%>qOgiVfbZ`n1Bqf)MRTiAUNqu{QP(6H>)u0J2ve_|mhFDE4&_7$Y^S2za z0Plq`tkj7Qm>&?q)A`1FgtcDIdVHgZ)1?>{1`>J0F%{aW6;*(u$A*nZN<;|yNZBGW z*liVjh<6zpB)G9Rqp}4fLB6rB6oXK(XB~mal%-mBNllB7JfI2v_JOH>&G^X3Kmcqe z^zN8Jm-!s$q0Kh^VR`AZq@<`Fc1h6e+peOX>c-Cu3+T7OPd5#(7=W)$D0lReLw6J@ zx4J;>`FjYfc-hSx8J36Vjlw$0D*};K$0!^8(s; zJ?>%oYbf-j?e89=ReaA5sqbyCDXF(^pL4o5a9dQ~X=rDK{iH2;K)17a>nJoH7aWxY zW=oSZf0)GG`29;#vgdNOmBHpIKGf@`q-)#t*FH0)q%pKNp^w2QqnmL2MY#~S`Lhv) zQje{;qF4+oDp2=fTSWsM+)?RZ-qu2Y5@VDYg^viwK|&BX2In4ef*f1^8DNb#zU|Q^cGGXC@qLX=!$GEwuPiEMc4m84PkRj$I!O zQ)k3u>7JN#G;;ij~g2N0}S>ofa{G;t8ix zYGFd60Z0jT1_=Ve`f&}Or`K7u44EdfVh?qIt)WRv+AE9BE1FfK2(>StA8woUsH`Cg zoeY4Sy}sZ~44!UUz`YT)o`i+&0bVo%0+NAg1lRCb9)jIxmEq_WXR~#aqf+O#Q~U-+ z2`{_maG%tP>*R~|#H33fS1LvA`g_t-UQ6q?w$!I@$D4EPZxpUjKXtTmWS`^QGn)dp zHlr#?%OS$*PEd((?h9W3hrLPR3ab~~3i(Y~zkxRuUmXyoq@`vH)6}Fdx4nM*qGHIU zPx@8Q*XZP^TmqOiU2oS(OFtzZ_K`hdmGzp)N$qH37y`uD>hmP3o#dIfQhMyhDaaCr zuc15XcO$bQx^SDoQ1Pi2lY&WXzR~j&RCRy!vgc(Jck8!b2(`q!0A@mjaD*Gnvt|61 zI?RT2o*_+X5QR~8RRPl5VN11OI_{Rga$V^cLu{{$dch#h)jy^b6^ihD@U`1(+Z2mw zR(Twl(sWQ5Ne+dvOT1R3$GJSsSS?=t-iLFA%#8$Cth)m_|CuG&qxjkKQ_O`Shs)i9 z08`en9`zL7H_{5Pi` zW5t6`0n|j+ChM}3-b{yhn#~hU}Fmm*039=eWORhS|&S>s{|P z;bBxA+QbA`e9r`1DN&J!-YxLHiF8yXYpo&02H}sx_b&vy46@p5m9cV2ay2k-2>uv$ zP`E3`;8C8K6*+U$MBR%8h&qHH zZ^m+_c88A9=?2)}*sVD_bINF&@Rv4DG>U1P`}g`>f5~?`f=jJ#w29Dt%Y$~I6%w({cM?%B)o`kW9mqQ z7U4*inH*N;4J$xEJ9~5Tlp{P}0PbJ#`DQfWM7|fFKCsH#zSCi`+mpuqrA>2U#6NBC zmWcUgG(>`WbMCXkQhxQ4WW*@%&YNP% zZ|HS=(-jtxlqx zfnc#US^&2vuY|+zKqd_qSEGZx)Z$EtIff-N$X$b2nj&7%6@$o8UyZo2F#X zV~(YnF1^w}iKaUQV0CxXJ{BpPQ0MF=h_jGNU3?d*emA~XGwIm%P%vXy#S30{)savB z5taK2%cWF`MXgpP{-b?uREf3BixOab76o@CVGumKY$XPVj@5&*Ei~{(<4hO}f(*z& z3?VpXbnI|2HalXLTV1KyuPL9Cg;>Ws)LPafLWcB<^BiZEYq1vq0g;%Q*ZP~_dHbhp zmL{EcxOkfrb6zgdMMQ~>uD(tI^N~37Cdu5XlIIlt&f(N4&mmw9=*ZA!gBjqI8JU2S zGmN@z&yuKE!{`1nG?y@fet~K1$KR)>s7<@-c9o`kcL=h=xl(nYINeM12?#HEzYb#< zf$p;ig20wt%V7NE0NyQF%8`NS(A>QLScPYxGD zn4GW;U6y4+H&6)YIbhcJD3U)_L~r&t9UIZVVA*Tw<4MFRxQ^Jn51<;TxLNF&8nz zPMn9oNCaTtBtOKorw2KKQcZ9pSNrb=`@vAv&sQE?fRG-NZUrXGVKiZ&MA~R>pnw1h zcU!gNQH!&$<)`qhj=NG~>0o}!LGKEFG|f%Ck7}~-&F=|PFXzzUU5p|eRZ%Kv0#0)E ze-GqldY1ZG1H^kC=NazVc6CIS5q{JKTp_LZ9xi%LZYgmXa zEyVR%d5ArNh8?H=e3c@oV?SE}bB7WJaN)yww4|RuK=`LqW{$d^asReRju{!iz8XFi zcYp9_6r{&t9{lB?jnav6Y4oOM%r|M&Cs6*b)$X=?B9~lW87OtWWX~sGD;~b zAk2)xfwRNn^%Wj-OOElV+i|!s9}hJ@Hp=sfmq%r;Kw4=24C@wt7>8vaqxHP!9hII< zaf^ARhgupFtGF5ZS|s#lC2Sgpk9#5kcy2!&{Y93YEN0K5=B)6|*{d*-!(DO~i5Xm* zJ3ks;>1M+iwcGE~hoe6bWL%#sjZ^q9098_~vf7Uvv#_d~YZU)hctLKF{LF^|p2ai8 zPZU(l^WA>m>e>&Z-||R3^k>Pb48eLPLLPq<$u$>$Zvd?rpPR-&604ndf3)w)`G&fp zz(oQ3-H)9aOyp}j(>%lTCaD{c$~&H{laju)@?{9!mO+g`jY}}SAo#5sUd2428P0~F zYM0mvPTk@xf8!FIWEM-p+1I(as0MsPc^qov=ptHAP&7gu$9dW}tzzoj?dY@s@dHDue)` zk_?x7Z6k!NH!lU!^mW1qiqUz6mSqTXM-!;vBO1pEX*OMv3O}UY-|QVwq*KO|rX&Rd zK#`&-TZ+DD@I~-PFMHmPso!F9jyvLX{kSCkxC(jigm3a*+(&4*Jgkfmn+#=icRxU5 zMCHCusER;e-bX#rxmNUUF<*l%PVC7~FEio3_yltHe^lBM?DOI*<8-j?9HmA%BMkA+ z-mrW#bQvle0h^j&pZ!%+Tlc3U$|dr^t)dILLDJ6IS5Al@ECxwHL+=m_D#=5K?u8$xpT(w5qHLj6q58*{DgJR(OdOOe7&ZnMAC%5R8`>cF}?k%2B6 z)53}(XBWe7ldJ@p{I5ISsy*JWy_f^QG6g~ZD>w2OyMo5cTi9){QFru#%c`OY477+b zR#*|($kooH+DoON5v0nhwly?6eAeHYdK{LnauuMMt-3%6;xNoZ1@{f>>%SG6&( zN&%WsOaM5rf9(!$i6&G|d%fu=@OqTtj@RJ2~+<^Onkm`cDX00UO} z$Vmo$AMM$szoy%dND6<*b7d`p9itoArZEBFKsasHEd5Aui?X}V51H5Ei;I?{el!7Y5?W?I8vC<2 ziKxlG-+!~mCW=uJ^|m;^bb3UvBpFr1=M;7pbn+H13BbO|w`${Zw`Q(mH8p8LRfJRg zf-?WqmtQ}#Ei&Ozg{tw$L@~$7rz$;eB5C?j-a<0NYF+fB5@B`mmU(g9eHl|&%VD>< z2_4HhUm70Y8xF)slMT;xsnRf{=hh0W83vh~zh08_rEES$Yzv z$OBc<&u}V^clkb*J1H;8U^wez&{_^JG%iyaR@$T?p==h}A0yTbVQ>27+za1Hly%D6 zJ!nO=v8b-_gGfX80i&ORj$uvfV3dpb?Dn}X7D|LjvQTsFUbLwdPr|qtAow+r!4Bx9 zmYOd^J%S8&%FsGlJ?A*=)NjoSbxbb1%1ml4E}m^gy*ySyIb%Oia zQB9!nm^>;FV9XgKhB1QbCMh@e8bjru_e~O_96|bGUgoP zAp_KOMj}A#>2{ZT6$u>@IAfq9@(%=mQT>_Q#FU;fETb?ubH5 zpYo7xP?9PMMCfBiAy9b$COXE}k~KATHD->BJ>if&bMOaL6FZz;Bf%B_5L-XQT+Np3 zP!(2PiE?Wvf@abiv**Df8?!vUPeZS0rR%KF$#j@f#TJ1;!(eDamopT)uwt!kHyv@OI z#R1AyxPC#5cPmOa3bPxJ_G*}3lnZEt6935WKY=pQp&XRwMN#dMjH1Y+i@?CFIaF|o zFO%;IMVNv_J@odtnvYe^&H^~0ZsCfD{``XCl3)ES$5eAZc zY+8)RUp8cIHDYqcysD!H(Msd?rDa`{g`;UDY2Qv%ex+V;)|TOYm#Lq00n?JN@s7mL zhS6Po7K!N_N)P#=Nx^hLwe})peq8;WFHtW!h6|$|FH4Is!-T|u92@p!6BLLb04qWO z9P<>YrQ5cnXu@MOnX&g5ZXgOn1j?({3kp94_SkqpeWXAE5M-KE)8CduWb}QwPjE_# zucR&QYfwQDKuJ`}w~wGgVLBK-gj2RXbdq zBsMqp(Wm7X(6ZUK2y@+4soicIkr_~#vj}uor*A5NUcLjJVNBIf3*F91v)1EEBT3MD zTHk2e5myo-xTqu;8=f9)zQMjS^BN)9$A_QL-E;nwci<*L*isK^;gh;K5+CBlWO!aB zf==*4a%fVM#qWwC6Kn^`xVsf$Pf=CjHMU|BK(iaLAPUC=Ah$qT5ONM&3Go308O~6H z0i~8U z=9_iNH+c^U2q7FD>rrbpmpaYh8n<~jbtiXmA_~|CcCRJw9}_ANMsvY8=_g}734!p1 zo)KhK0_#{n^*f@_QoeUqWsrc~G)#N><2be!M7m^S82U^XEkEDc7@N#Q24DtYOZ>_$ z#KK4~>Po);Oav&)|Cn0*+8&&Wd&-d&Za%=ajU| zv1;EP;rJ(X1%72E9QPD3j=ZomA6FP*c@BGOZnMekt{53NEQ`J6Y=N=T5hnZuQ zv3-7R8wig%-fETb-T2`@@mI#xpg6E@sa+=juvHXAUNUAEtcG#b1V6=4L;}ZZt{{l6 zsipR#R%sabqr8B#I-tD#~f-mwKX^wlJLBvS(To#QWCArc6GgY@w} zQaaw2ZlPEafKk}|F>i7(-jDp@C%-l$QZxosw7xjdc{?J;zar&_ag+PZm99#_gL)!9kb6S|spZ@Gd)79$V8VK_QE{FCo*vp@P>-I51-+#_um_1xzXLh{r}^Ua+4YICcQ-VCco0!F6w2-On{-n56x%Q-=<;+Ym1K{3g>l)JQKc}64rCzo+8X<~*?`cxk zN=Yej#aiRvVqsbQn`zhh1B%hA$a+cI_SgN3ir;F$)jM|Cvo6U`zSurO%CI(mAtZe%~K=U|u0R83`6SG+g&>&p+gq-);dV;Emh!xmcu0 zELEkLSS{N1@n-1+ef7(S6bAuz>U0>Kd2S%cagnvEJDS;cV9{*rSQ<+{Wk1YLNB76E z_R*G%q8z3+(VrO(zzo^z*=(@vaihoH<(XywmPa}BLN3OxWeWMde1AV7(xRP#X~^Eo zb)yzZkuBA3_fv^1QyWEX>dnnxPS?HK1Y)y!i=1Hpe6=mmGVJpczt6|fP=|h^>#d%R zl`tgm{4F;N+`Z;Xxe;AJK0b*_c!UZI=Ax>RL&cBBWNmc!0m-FqenmrLbUjoXq6*gHBhPa`gTBb5SS$wiCbRBaO$QGHQ6~J|2U!Ku7@` z6!onar?a*V73f~-6n%vzVymzJGMf?XzKEJ;%1JEVJf=o$M;C zc~0XdVQVsvo+IVn`hc~tribrVf{UH`F`CG^Xc11tO1?oUX0q%*a@L+^*GV!_gq<7D z)IWLQMnh4_^smfo;_A(PAnng}n`&UwWYLd(EVyCla!ol?EE=U)LG+~>@ghKGf3wGw zWX5qv4cn?YF)^XEDI6^6)V^O{vaG_CTy zdBf*=^o55`jONozbNAQpNIxGO67YIn3m!KQHKLL0xrOa1=v|5`E16%f+TB61UM z&|&q{_d&Ku6mgl(XGuyXySkj^s;xncV5E+GD&LCVJjb1~1s7H=ZJng#bZBdX>-_HL z7x!a6k+rtu9D34${Zhy-%ne(r<32W8tH~iS$&DvD$u$9MojfZiD*vDA<&W_j#MN)< z-sS6DD(ZEq(>RQDh19Q|eDUhhpB|7VAsPyYfXk$;*w7%|2N0Q*GZ0$waNRQWO(ec6 zgnItz>qHOU7UWgcfDmpkJupQU=^<40B2^Lz00TyJN$Uc`_*lQwh~)S03=2M<^_C>< zMDpTS0|`_t_-V2hJ9=g08q$5}?Q{20va_#HOK-D#``qsXp4V?}u651_OQcjZHiyux z(cs#zm#ohs{_}FJPU$#u? zRO0@$4g6DF%clg{)qLH)f=}@wII}35!6lr6o+RYpaN|))yc*L7Lvep5eCmkGE^FAr zynsxa`)0Ym^BfG;gfb>mKtZ2aido0UcC~C+57CrT@sF{2TzBeJP9P|!tY^ds0ofD} zw)cfxowX@qWtJc(SBrbT%VGB0iccWWDLsy&I@6|y>e#-S61(nA}Y+Z<0-64t3ivfY((9wJsC^kmC_nd*C^Gd=j* zKDyY?Xk<;uUCau+w(E!8Rf^!{^FBBxy8SF34-8yc?~!?~!9AZr9TiAtd5C4Qd|1IY zwk^JjnG}GvZgPBaxC{V+xA>k!5D8)i({0S?is~K@YGL{dz9#Q(Si`j#K#%o_JQ1_2h~wat<395d0ZxX=KgTOwNC~4#MjN^AXrcoeNfJgW z9s-DiVFN%<)C|g#>*rO)TkadJ!EXbt87oBMSeR`rg_*3nbrYy$+S~ZOqT?R9)|pqeN>t_ zoj#Ym*0i&H2w2F^rI@Q|<^kR@3D5}$-EbCQE1EhVO@=r=b0{pn>y@de77z9IUqmF* zamR=jlCEhiWVIN~=@MoYMdM8{s@v?g9JZ6yVvg3EVmnx}o~ymDkA*vN#Kgpv+^j18 z4HezK^eOxAv(aXk&GHy_u^8qbf(2y@+Y4lvn*e|{DhyYB^0;P6;c#dxgx7&S^ahA8 z-ilV5$_KA^5k1Yu^)Q!5e=L5>^-(W!0t-x)z}96%>D`A)4x4qwndB+(#&p30)#V(L z5DjaOqT$JQAkY-qv>LFCC6Bi=o&6)^|MLaAJ@8Sn5bs8XKm=V!dRMiyO-w0f4)LAeb96pS3W|TSbBKM zc$$C_=uvLoHBm~+f2s7rlH>@8=&6z!{9f;jv!-wy{%mgv1&5_zr%^bjz;U?7hPsw& zb0>RaT7!FgvFd#Y`pnzN;K;zwUIR$?FGhC{4x!}m*^~QeW_+Ren4NS@a%?D~0lfP4 zbw-aHAC6(=zYJu{9&vpj8z#%E_kMKKgmE8Je1u>v2K=nJt^U|0vfzCj89Z1Nj*1Bo zvOp7R+{GPt9kQ4EOp5FF5t z^XIE*nDFk|)j9;ED|nV8Aqwo1_3;$FuHu*&ebGqmJ+(SXp$lbXCBC2p%5!1KW=Igj z3^n`?B?np~XWl6yJQBZP>UfXyYQd&_`%qREw9AMqa0G;s=%-<4bH}@L&;PUdFU+h< zXU+9=o~Goc^-L9|d_K2jfnpFeuFt_8+OKaE~*go)>#+{4{&03aZAXpTqNtgLP@@Os60~9{GVKc z^LQDMp1*P7m!bQBDH>W?`sSl7Cz9+XDJkL|NBEN$)(?M?^Tla?t8HqvLkz73I=Kgi z$-2&ZDC54$ar=^0b;jGZ&U8fX+LJbK*?Khjjl^H`OHT^Ar$BQDyQ%cP7&1_t9r8kc z+f#Bu+m+e#iqrE05gy$#M7%rc#l0;1lRdv`GJCd>lN3HBHteS6$j;L3Bi0a6WnWF$ zM3(_xKgSSNlFW`X61kE#_V>GVC`!hd5+VcV2Bw&BX$7?9OY zCf7qx3N;kDO?LsqppAv(zOX~t_hMGvadvbT7Cm;Q3%dbgE0Zq*CUN|Ifv7s%qaV+b zU^PNep;fE>{??iBuI0y0rY|Qtms<4X67t!{7${OQM;GHdNe8~Cv%c_n&WG#@j_Fql zioeXb5{Mhdw`(F=%DF=QEtU<&7nCA)w-4V##jYCbs*(o-`!w~1=5x)5tTVO9pZbz$ zmYE+_X$sT0v`82NaZ2E1SJPkij$m%ZOlF{B5sqg)0Pm*E7HY4yNp5{Kiv`JhE?Z+@ z0piUWniKUAtmq%%iCCHeVJZ12052? zYf?qmInd)8Y;`x6oI@=QY^{=+KbeA_Cm+A$IQxd3)))A4J-E{=n_|uTdg06!>|67`KGWF7_(sz{+n05U}<;JgO> zf6*3pOo_w*`e-Q2R3sgcfr{^B+1Gsy-816S-a|dKmv&X>ReqH_h03rSglIgV-6`fY zp$3Gf99QDRHnOg5e(W2jnGrjWrgHhy4X(_a~Tuc#6-&8~&vm$@xX>J7?L))s z1TYZ|15mECE_KBXySdO=;90rD1$M`@O^T!KVxApYy{uXr{d>)Iuk?oC&@p&jL?jWi zV{2rCx9DcD_8z(+c}6s{c3me24+)5);#vJGv$>lTISQz6b;eXISy8aW*Eh{JnWDpr zl>dDwtPD5LY^zXeeHS;6xiiPCugDs&iMU?jHwR6|Fm4hBb#fMG;C}E9vHGF7!#Eo*cKnKma10fli)e8NHjw;*<2IE zX=cHw@2epgSdBUURK1ibMBH-s?*l{$&c-XcQO+h;-8>Do(LrL)eqoqxF=k~R3N+aXx8mvOub5IN~xV{&Nv-I-REHQNh8ROnGlzj4G3(D~U! z10))cikXF9lAp-C1jcI`6$IjYvEC@z@b(@@nu#UofrdV?4KgHg8E7lnFj?3szfzAg zeAfQ5f>gmD9OD<1E%IRL-DruZ*A;nG)88wr$>{~GF+u?_J|T+ZI7kCI1OR7!+Q1KH z)%wHorT%Hb)AHf7#3s?fCh4u=@cEfUYip9fkGGwOT$DK!hArubiz`8qLs!Yi?NPTT zfqKjXVFc_U<*ujV!0iR2C5XoI4a}~AliDJJ@wjv-;4_;&PGRA2TLWOSp%pkO#ywmL zMY!RUD7;}{1>w0-@c=+Y{ytF$(qs}4a$`VnbsqsS{pU&R50;xoO*MFu+~ci4jgfay zPN&`h2@6w_M$Q%Ar6aT2hED#5P=cpM!^t^Ioy+F`(sKkifu^g zSb#7-Mwjy7rA|Ng@VsS6@h6|4b1sxN4+5%KE#Y8+3BC^Eu}@cp@m7n<2WO*&mneNJ z7wR8uKbqY$Aie`UA^`)zrsy4?!mV}FjflcjhRxwL(pcE#{EVAqdiyZD@{*-M<;nnx zvtjf1Zj;0uatrSk2D5e}j=n}{z}m|GmH}=^{^201&{Inc8uI%csRf6#+B*kBruUk* zd{##CnOe@#E*4e%3?+gI`ZOFniGtaEG}ew!V3YN!O0@S1yi3W&l#j=%0GIcUP!)ba z6Lfgyaal!~3WXmipK)9)OP*LmK5eZ*DkTvxARwmyr8lO!WT+3vV?^}w{Pz5N@Y0k>r+I}ax@4TBtSx=%iE(OH)tYos1oGqdwd@&npa1ld_(iB8P znJO;Wc2u>Ocw`$Ep%qdM%@V(Uq%t|2ngM$c5@T_X&vGyNu!|0PoI|JSS>(g!15JJg zBSEd)361Sf+vz!7jS;=@Z@9QzJ=E~R$9=Q+hR0^j{hN&y_w`BnCPxs^GocZJLi*(_%@FXW(G5A?}&zrn1LZv^WO!e7(Lx zx7B4-k-cyOm)|8=$@YcvpMhI=OU&@M`elPq>>9nr(Jn#tSS9X4sEM1WP8oOJ8L^W zwCf%cf@aG6;ljlWndCAAe?d6tEHNi$GaDn_$Zbs$l4k+FEDfR+$OOq1bG}ayU@4oc z@dZ`hcl}65-M964jW(yq3yO;!XBx?(Jfhdz^{1_Wi^B-WA|Mgvi>TtQCt%J|jw<<3 zs!_zhiNZ?JEfTMAKhR+1;ie^paml>X!xV1#GDFHh(_LDJL?`iAB2}MmS^sh4{P$F# zrMil$9f}4+6~BwAWg)6Z)KBJyF4Q;L!~T-x+SN#ob6welj@xO2r9zsv3X`4ZRpRQE zydqUhMZn+nWR*tuFWwk!1FZU$w=q=i=+5uH!v=ta71OBFruS|CrX}yeAhL`YHDawW z)55}46YLab6F;=8i#*^qQp&s>d*77hNpIo5bS~Ey3J;C*LCUfcG*Iio9n*nXwtr`y z6Me4lljMh4C7k)LLa(^VeB3Dgma}aL0Fq`I>bBZ7SRbmg@862w@Z`wv7aO!A#O+V# zIlw1E`8rbJlF&g;d0~vd4cK9fyOgzk?y~B|7aJ-0+84LHeva32LbQ#7bYUT<0?Bu! z&%S}MFyz7l{EEPZ-!J&+3&Qe0URiawW?fs~G%brS$35A|pYT^IoR4f5jh;U&04d&t z&GvgN%^e#tjh~105UwcvH7H~_R&pU8Ll-B7d(9cU;SO;ODO}N=Cdfkn?Q3SOY6v0ygV{QMyk-)v+NyxT;y`9 z{Cvs9?gw{OB0he&3;uV=+ErwVwg&U;6LpA;Y5@iuR0%Ss5?1L#bTvou+)-bUqd-)*mwAyF55 zzS2~}5aR5&q+j=}A*0}|a(Y?nZia3-O2#s{h&C1@9B3lO?b4N@1q6S`f&NXsfx zT!qRtd7DI{byc#hm=MTp@)C&D=|C#JIRC5@u&WZwDY{V~#JBYCyr3`dRWCh}j5&F` zVmH33c}tfNP>wTEk)qh`M@OBj3(mSg3Y#IiK_I}u82>`vBOR6>(uMn3WQD?Z<{3Yo z3n^s~7g#s4dz1wacl44)glytnr=E7ubT{+Gk5-Q-QlR3NM4Y>&lMlBk7CIb^2WFqs zw820!TdENrC^oIBT9nxno#V0by*LsGZDPjUn_^@uZvItCibRdrIRMcA+uVHOl zAo`{y@O?+V&LRnQzGG=Lnxw4?T>jCyIYt&{pl=Za1LY5Snn*}KHJG> zA(RvU4;D)ye2i>3RXR?S0bQWyWHy>=hbgk|9%eO=07ws+?nFguB(W+FS@Kh7EWDxp zI^UW(^+$8fhhqXoSz!9V`M7Lw^SgfoW)5Y^FbOD!S0%mS?@CX@ABE4bOUCGq!8Y<- z`glMXGOx{D&vm6kJ});Y>su8w_3i4jgga2LW!ar#U^xTC{2#SEkdde!xu5yprEaoo z$pE!OhGM&37s5PfdZX5QJ*C-<1i3Q&ac|>Rs~%p7oOy?#fxFt}rTKlW)WdMoSOS(} zTC_!?p&J*&x86MXC=G*11+9arqVkN0>n+}1#->ns{Q>H>&dT4K--VsMF3NDQ=^N)x z^(*5I$8Dvr$wwdj{DyHKi8aGx7<{@}RQkcTX}nEN?3BWvxAg$8@JV8FMWNXH62Jlx zVZ(>95rkG>S&h4bxeX)BRYcD1gHSPm8c9i{NtXdP!wZuQ``@UJyzmoljO%->&{T; zK3{>fTDh5(Wsa8>}pU$^OCY*mpms-B>gU!w&~xQ@>5i z#ZvB-XI&jh=R4}Od4I-T^8cL{Yc;(4n|aA>3AYiNIE^j!rhPxCIdmVk6SOquvXMNj zLx;ILJTVO}0RRhOJz)nn2nE4-yz|KB@I85)K>|BQ521w8K){Q`=C0Vtgf0Fcp={`W zAm|GfjK!pTkp=Hzou3CBB1x1fR17Ep3qw={495sq>=7i8lESvEpyhLnY>uA?a-u8u z-H#}cq2*MI4Ce|AXP6)YNzm;(rXx>27S}>nBR|LCE`xE}7r9?Cb#T2G%JW<^c)wef z7#L^xiJ}ztCEt>ZgXJ{ATNuXCl)ZzWp4UL7w7#&j!oIPDx4Cc?ZwU^Szxh=Zy*`g( z&kHQE7wh03efX4~{K7cKh0VV5<{?C{;RH5+G27R-yF75u2&x_5VU*%cOF7p9L;d_0 z8KfGdtZ>R=t9y(T?$-j94!leeU;)3C9M#m!Qkq#s7&>5~220Wg$5`tS%n zWK&VCd*k%8^@r%kvee=6mUOT#WbV z!}^dFM@zn*RQ{#(46MpDhaygLso5=H!(L4<7E)|t81FvPE4gqjN!rkC4L^ZiYnuq3 zGGJAMA&bA|ZWJa&4Bhjx(Ic!4+^J+S9_1bF6Sr^H12M^c({p4VkwZR7+s0DwkifLM z|1%DO-(|+%mkJ*Yp%p|06B#o6L%_YXTkrruK)%0*4VI2P>X;O%n(p{vAX$3bnh_2; z1@QfP`qJy#%;%jo$%IwF+`|~+{VA!{oF}<1qL=BI?z{J>1YS{S2qj+)Vf$#9yA`;+*#9CM^3KkxSdDaGP-iHS>aNW98Nr zA@CVCm@4DmhukQbl)616-|nN~$J7QI4eyDy1kz6sd&?VKW5*}mIwJ#@p{;{D>H9@< zS2HzIr3O=B3J&xKLyK^a2$uSr74Upo2{%tkd-R3#Pucj1xN#hDRM`D3-nazsbY_&Aru@PJO6S4K%<^*dzc+3+Hzk7Kx)D8ChOuU`u5 zx+>+ZHT`wWkVIb$MoUG|!N|V4ax4-zTn*8j(!VKxkq#{0DKyI4xp)t;dP1iwS3o=|j7>XBd4 z>+3aq$F+iYTi8b-()Z6U)Iq#456b-5A`>&lysk(2`w5ci>iKHH)mhB`v4q!Mm&Fr) zj5(tLUG}YmC(1W;CSxr^BW!}F|54G_-fs&T{TqW;VBu#`mn-cF_Mv%pffkSK^SUwy zF@*zyuWE_TqeS(+{XQz2t+_0u42`18cikLhRG0aUN4JodD?e8Yb+B!?U9gi&s4QG4 zO++l1XU_xeM|c78WKJUD(ndb#q~e$Sg_>$*Jv?gGv9T1KkhFpOi0 zcgVkGrq?6J9B5Z?(Y#eXtay&4YWUJc9=+chGRq&U! z6pr9Xs^rW!BR&=?(wluOD_aJTT>>|`Rm#=B9tGvju1{eE48$qCO#EPCmaFx6h4raM zn-%xBk5t(2wG+n7~FWeuQjHt`6? zCPL$1HMfGE(G`R?H6|lG@8HzJ2|Y8P2`|7@CK2xBP3+PG?x2Lh)!xZ6+LBUtsHh=9 z(EzYj*xJPC%#}}cNljVP5#?mZr&T#yY{L8o8#K(*(&ir|6ch-rxrS?XoOD z*cm`=tFBx(|9SsVFm#{iL4ie?>ZW7fnQ;$DohJ3SZhaDpmv#%~?S#AR~G4l z^Y_6Ex_*K0m_t~}eKB_+K*D!S!->bhk$8awx%IDSo!`Y2ll`1A7w+`C|LjsYojPKZhqM$OpHU!K~I!N!&(9r~8832u-hE%%M0 zU}K)_a~dsX`RBm;1FMNrSh=skAvU9)*E3$5LCI4CIf}MjHNRQ4=?A{r{E_Dxze6wNIgp1(tgRm#5x9fOt%+| zcG?8*nqUIdrtBT1w(i|p`td*}awpG^W1{(e(n&a^I6mz$< z4D6<#5@j<#xp`OTqKWoq#J_eTBR%UTZoetEZ}vy{t1uLFwlj0oQc5_O;eNW^b((wB zMD-V*dUC!+!`SLEz2+XLAIY&YM4@&RVQE`=`}Tsax*Fju40l|qku$IP^nGV8{dqMv z=*==N#mHX%WY2f9@h`+HUq-?cV$xxgqRL*J%JUE%zJ>joygtom1+I%ZBp!S6y9g;s zA*_2-c5`xDAv>2(lIigf0@4~1ddHS|kJd^7J=stU*-F5CAcZIZFgwBngyi{Iq$sdp z0CO?>Z&%#;JIw|wmLkV(-I5D5r57!SuD-|Fsav9XY|h8F#H~y1(z}7_AIrz&F+Mal zQ=rHWD=TT17HM(#zv3w>a4Pjb_}f~ii6N`OKq5Z3rSveHP4BW~aGFbYMZi6c3ZYvI zP0vfKs04fe+FAuaQH^Hp$RY=nOk||8Upe@!IbEoXOHA?4JoMqyY%K0XQ%J3+gWypt zjuW?b0FCB4S~4$3qhTc_t6`k`C$aW-{DbGE`)Q4;=+S4YEGutMiu4humSsz#J~=ot z{-4~)ibtNP>(|SPkEJwI!HChDv#{DgLX(^iFu;De&$uR~<({35jw1;!dz<`Q`P;48 zZ8hAd@J!=_uyF~mii$DhfA$A#dLM5R9jDX!hs0xPyfctKv+t}|+Mw+KKhqPDPn`(x zmo)WF>!zL_yw@p{jJz*!=yLYdFgevJ++*TV^`@50=Ei?XdD)RT4^#ZlIf3ERPSzu0 zrF6gFsKg!__Hx0W5;qI_It$AsAkZg&-=l-~!U2OUF@a}7ru)=IRDn7 zmxWG>g~M#7sV_fmqIR{t(jxv~gJ8p6vZz9s7=QP1G49&m$m1uJUnoI1erbX{9 z&w7IMawK69^ch!m%QmBe0;&DsY1+FA8yR!#Sb8IwqA@kR`Deb}kr*;N=^O9=P9#(? z3s>Y>u8M96q<_CRYSX{Wu%qD_!R8F?kK;3rRI6{G03OsL=0ED+Bb11+#)4o?2KBrk zibjng2$i#@run%+;W{o^Kq7@n32oIw^w91|cx4P+z_uV0){!Sp>f?r#bbqxs{-}@3 zrhWA`RxVy(b8=jU8GVJ1yCd{b7%2f(72-*I$#T{Wf_tL)KK3yclSpg%khvHL8~Q}( zZXiE(Y2Z{Cg#qbd>kWta<0znn zl6xiP@a|ATH^!Va-hMzgYke2c&=kLSiL9%})O5#|GeWUX`a2EI+5#>0Qg;@5hMENp zz+wG>{P#}1*6_!lRZ!yr#5}7)1YU{zGmt3AOyT_QXDZluB${4XoKvxuDW}8oax0^7 zUDiBBYv)UT7K8HWb6a>Bd`y};w3F(lVv(oKdUU)UYYAYm=jhdsyKfW8CsG7FZ zlrn2$>HiZV=j?A`dupi}4mX;3Tu7%x2sXYDEyU6@pTeX}q4c12bOMdF_8LLm;`(n= zH4m5b>gjm1{X%a$GYI2aFV&R9l0G434NFgt7Mj9!t4NokZ(sDr$NTBxC|aEAYg4@a zpo5=a%Z)y*2Jw5MUvV^CYs+m~(((;%uO-kbp%&KPpmZ@fL2|a}U%SsG27T5ux9qR- zLu%CjASgV54G2da0Y4#_LEG*b@JV-7G|VDJN~c)>YsK$FAAMSlD1SoK?962Q(ECsP2b=5y*)iR#l|{~jf)7nK;6rEYiK`D^1d_T$-d*jo^h>;@%EmP?8BKn_rY zR-IO1JhB$~!CpPxxn)jOb1am>f~T57HlYKz!D;^4(oQx*me2UIqad7qf99NlPX6%4 zSRbOSh5!Rj1Q;+HVZ(sJD<^oUtN%sfd+!O<5!txkFCqIEZF_ri*{XG00$sC)mhe4E z=T6^f9l(oVNtv0SRo+UI0Xp8Zf7#z>bgM`pTFOv zLv)#>6PS;4mcf0r>H_kvkoBc{4)*)0fD%&>Ya=9>D0NXevcw96=Xg|vKaQglxhl?K)@KXU3DKfIjPX9l1~!HIjEZ%-S4kXLVjI` z6afm;+5V{e|K`zKI$@4CnTI*EAjh-naWcKBXLr(4M*Ql=xYq#g8mWBYR|>lS|IhlWVMn|nD^ooxrVGE}Bp+G}qs z$KfV@><;*)bg!C2U}J@0831%@v$QgTxGJpv9%qhj!jCEvrQs3rdS&V_rZ>i1h zX&?Nc3(a+1HZ|1Kj#HTW;2nlrC50X+PbBE-z{B6yh;xTeE^}F_Df1_6pymQQxFbqB zLpd!z2D6!=3evt5vbu5T@ETYEbT31U8xLa+e?m#Sqq2lso%oQc+7*_cWprejh0g_! zrfDBdJf*lNNvrDmSw#m_;UD^lmAR_XF@GVm5O-tB0|FyKnTHrG2BOX~4vi^PHpQMu zitamH(HoEHU!w$#5Y}SJv(F$584 z)(KqQl8uegtT(zN9*LOUHyspXh~3?J&V$?~UF39VNmsk1u_NoOO;^0A!+fKR|EF_| zoBVqZ-2bcb?@M0dJ%8D|qClO}u+%gDrW+X&#koot0bowIg9{-($_KCkVM?!B=aWf| z?#dbbiS&uvzhs7Aagw(>-Ysaevcxu#!NBbsv|}jE;kNu)7gF2M3;V5$@-5LM4W&)L zDg2%{H=8WiJ1Q9nN=~Tkk$x==cAY{R}8P6;Rw+~`iUcR{#7QEx~4?C^ypw)6nbY=kz+vvqs( zRQwEQZj;fa!}w^hm{;ae@Lc}}z?{s8NM6Xx@PSK0>__U8iO^cKudE3hN0j8O6-#g9 zZMN&bzxaS z{W-8$_*^~g`6Nwur~w*#rLCvOZ4r*$jgYI*ky$P%+q+eD(OBa3c&$t5FExUwKjg0d zTpjbOFNleP;`N9QTq3kuF}tvTIWUIkuX5YsZ5uAn4&~?vzJi3K*dtV9c;Kl20S3N7oUfqzZ!2wh=BK1+StHsS{D9#trL76wkst z|5ck$?cMsvFmRTvj_T62_FMP+X44_Xdd!(m+E-ly#-Z1kwk<$^d|M#@9PR+JikKQ- z9d}s&KCBcENV=;_4GmP3egoWQ-WA0sc^m9Jp=Wgp04!{RfXSy6!8&f@0l64*xU zRp)X_^3jsW@a&6NuGL#1t&x|uKFnn0EqF&n>3lgIoCyBOeK-<> z9-;moS$)zw5nNehq?TGfFu?6!GX^fFvVIaQ@<)4hG=r2dZ!+dq$%}`3Z4#3uhkCUF zk;k9CvDV~=LelzSmQs(Jg1a~@m7}Bpb2VuHL!LB_ir)&91tEZ2=d^2<=t1;#v?OA7 z&91wdeoIF?E?7vN`WS4tF)m4!ccDmQtP%{t{DD_z`YTnZzZ6)O{q{7qo?WI9$Ne@p zssktMy4WUVywAwuFF8+MQ0ihI{-k%)m)8I#0TfY#2Ia>tyqEN#smv?q?@jN&FZ*-` za-WpIX;}9zJXCms1wcSfoZWM2D;QVfo`o;ORX}`;r>m)nID6k+w6{avbNc?-&q_kus92QZ&xmb~WmQ@Lr>2 z)#{U<1ajCClP;A%R9dE>umXWevY`Kk%pTJnU@&8Z3xjS{NPEKYh=AK*n@wcM^5^+| zspzz066|Gf7Y#t617wQ5a#K)2Btka3v-zJ&e(q8D=nYrcn%QBh=dXDM47@*NT>_{# zm?9x}=EhHlK1W|W>#EX`ol3zTiul*t@CDQ^>r@|1zTebtl)=6Bkz3!@(Q6eFzhVv5 znnYER#4%YN-XFhD8Ioy#vYx#C@qmcx`LR9qAbPNl0-IGHwsWW;QL5YKU&5Y~*B&~_ zUXiooTsV-_=}CPp^&pTDPT$LXZYXfvOIZ0kCkM{l#|b#lH$h7#fnnFaTChhkV(RJmsetV`1S30= zD#Gm?##F67NKJqDcSP46$J$6|WuRJmM%a~V)FKve`^p4^4K~;6ZHmx`qO!>fRgvf*5_9BBj)9M^Z z1e55kBLt-YOWr*KHcSWBcTM8aal%h^ zHjjY}gNZHJ$BTkW0Y`j9n|C24*Z=XH{!dN5ect)9;eD6yx*sS8K-)W~rN>^o z{#7Qb9fRY$=ty~oj2l{@0`9coqyCF$$0T|Gp4bDz>Yh4Zact+vZ+XP0%o;(;ViYAW`(AhPCr^? z4zX5}x+fz1?7|HYIKaJULxnlb|!J22}T_F z9H^;7ML=F#e z4s-Wwk@c8vI#puvn@VskH_;5HyOMg;ulAJWzP$c~=@6fck9D|*Z429J2@TpH{FMXU zp-H=O2W18yaA(b$?x|@MKU_5J7r6H*wrMX8W9QP<=e5V@ANdiU$zIB?=SS|~AE3NB z!PbpDcvA-6z8}fI@zDSKFQM_&+doGSN?nu(R)#mD0cX>ccdT&}c*f7LrhJiGt-2u! zu#o4p=Pi;X5-0V-o`eKy*ZZAZa(q42n5^dU!C!<1@yKqCwobmGFEr{pUumPi4NLIR z;UA->f(JY3xlhdan1^$StOXbS58_pyH@3yJ`hF;G&euaRNb*GDog~THQxp) zF3OA+4_%O2>_&4M0h66E*OG_pabNiFm^LZwPGtiF+&`RdOmW=M?V2~$X7;IkJZX=q zE4#|}z|l^e5XKsO12TQ#y@W#!Kw*h*kgeVvLcDrO(gOM3m%cNZu$z0{#?t>CkP3Ks zS(%-?auC0~U?vCF%PF8X;^qamx|aobbt330?lwNT#R5v4>K#+~Ng14Coz1M~%6PUG~IfxNp$y2~z=)di^D}m)hJTA){8=05()uV>#??GjCVIlpe za&zQ;;Me%n)5xnWeQht5mz$}1u*m9q7{sV;3B{sP-4K4N<>23E0p> zZ$V!gzg|7>f_C}hMnzyPjO09bge^3Nw^w>kx=r)r-IodVKi7fF`6wC6hZ3#Zast@3 zMQRAaL|&m4wnt&`|LPX5sIEM*uKV%3b(o&cgvfowRARH}gzw%|E#GanO&(S}!Oc$Bq7{u`rN5@z6FUD>{) z>)|Wfq?fZKtflV3t%vyQ2G8=QEPS*lKUq7sm!!oi9`QsHdQ}qwwsbTYOn2jsQ%{I2f1H zMJlNp=aR_GF)X#E z(FCi13Jn~5QPj2g5sH*l_@65c%rTw9L4K$gS2`+S1!8`|bwu?I6-O2JGsvaiLllMS z)~);xSNQP<1i(DP`jpY^OqVaubL~Ou-J)i)=i_N(fv4E(pBm+S@cFdTu!7NPObdEp z56ba&A1BhS)bk9H7&G>z z*x3=Dh>B${vgu&IZ;jH-j$Q3Vet|y4$9Xo=W8WoH>UgncWR<`Ca#Tyf*Z$WptgJm2 z(p`e_4|(=oTt;~Nll{=&+vD*cqPfX2+b)V~H?3St8^M4sFN8 zSlx(?#b%@4HM)dxX>U$D^SQ|&@5*tdKGT1N`4-z68>E&+a0=_S)T;W;>1Ercc^2X4kq^Vj8n*rIR;^$Dfct=DE z8A*u8UQ=>^dWC;>_IHHPtPe}DM*pnU@Ggiwb=N=z?-Zy8U*RIIX zi6$RZ|Ju?+W32ShYF|XOvDvwv0%%i`IyJh z@bz1u|dn!-XWN2CQ&S&`l62fq@+(3^#`-Tf<+Z9~ERY?( z%`x|P;N>{>>mC-x)Aj)OjuMY84GjY!{RUzl5FKTd7Mq)4+F*-51Y>@c-DV{2^1T{~ zrnczUUOin4V}nE=3VIa28)!b_!hp6{T0A-$0|M7_Ok}dck-~9yBiG+Q;kaKmsz4pl zvE$$*S`nnyU{ss)UWo!`%1g9@F<4q-Vjls&vX#9jo^Rl+rG6$dW#<{Ws(h6#NmCj?w!kj2OY>Zt#S(g;iRGa_XK;J)|S4OVX~74i9?{U-WfBmDKis# zDcQ37oU=`)X>1?Qagfdb4nr?WUPzNp&(ysa+3|fY64uL-`6_%tG`CT|S9vYSNclJV zJx-fCc2TVIztn@$V=kd7sk6eIatzCx{#NC`2Tv~WkDZw!e7Vk6syen;4=A6}DSRBa zswS5Rb3EG7kDa6-)7_-qv!lyu8mFtl8{n>t(dR`_6N+_Xymu*n&JlLA+)o;hC$ra& zEL9NEyd&N~D9`R1jV;kmj^Ht|x$zrEYE#@OxF_&csYysjFY)37ukA4ZyoWiNg{?bo>sw4SYT-jz64_6}*kAlQ zL;oKT(K7N+$<_Ir{;Pub_U!!B3NoIruIp<_B<15!x8(!iGye5wA5w{L2DRXFR4gRX zh3u-tRn2iL@);#^e$RY*YNGIa{M7zrt{XPx^g(iM$Rp5*q;1SqtW)j}_}mjj+^PE6 z`&E#PUN`krhqC(8f(D}rrugCoqG^C(wlEPqfcuB-Zw}1qtkkGe-!yA{ju*V1!ohp_|{EZAzHeer3IygY`^# zTdq_D@uI^F&SYOsv)N~q0&dsqcUTi+b#c+vBDK`u!3GtB6K4)@CGM8#(-w3*H^`>o zLbAq$gtz*FXg(->!BD%={=zo0hM1e(`3Ix4*Ed3c4zVc7nhFYh`Pm?=eSSOB`ct2M z%(Eqh--T!cy%6jt7>pJAne3m>r^}1G)Q&Vl+6bX106xG;gtXmki0(1a=E zE|%u$i|sdk*f!h*(Hz1w?y4!vK?6U<|FBFez&vh}?&ceopX2O=TtL?KneA4Vj!ILo z$hXS~enhlvtrRH@F5vlrjWJ*e*8zj|^c;EYWuu15gQ}*ap1#Xd5BMGet|?3GfVKf| zqBu^4(Goj2zn*Jr4{o$ReJ075%Otj?kwD+__lwClr1pC7HgvUvB30uG{B{Hb#KBY~ z`Jdkn5WBCzP6Jb;lsd9c_$`pMez2wIU~wCnGq{+@_k1`<+xCVND@7oHc=SeTr4Ng_ z1nwcVK%t?ieF0hTEDK>LTM~t*Qrv0Q%J`2E;r0bIDpYlkK6AICWXWY{V zJk=}b+qwL-`5J=6zwruDCPt4aTCuR-M5xC`>+nNnD%g(0cpiZIQcib@hy+VQJ=lAN z*%0NtM=Ft~rp~U`;EDRe&Yl884(nahbiq8_D6M0OMz6C^s-c1K1>AfDix3ge(JEhd z3Z)5U?W{sMm_+-5cF|PV93JNZoC#jXf^q0#>y<1S>K{Z;;G7TTNZ(>DHiIk>{;i<{ z2qlQ@eUr&4BIooQ@zKg1|1HZ+1r#CYxv3e(-^{1xC~e3*oZS2;Fd3JZPZMFltR3Ob z?sA8AM*MS~P4)YvawUhFR2Ompu~g21(kKZ0t$>ItYmMT`U&0Q$1`~0VL-%xR|Bbog z75`#qsUYdsq_Lv?n zxj?lr>Un2X@$#zH(tr|C5K29ZDY)oU4kZy*ylf+LRJf)oB%Y7pa_tHSsv1Y2~ ziwmDL1|r@yWYNYuvz_m~D-B+hQ*y-84-x2$6q;8^#`&%7CihDZKAAiI@n^>=H&jeuf4_lKLIqaTnH%f;&$M+rU zzkf==jHVaaJwav6UnjzY^fry2Rg>=~ed6XtlNRIKe_Or^e&}I9Ee#jbJrCt<+m__+<@A&%?hT}nh0eKS^Qhipi(d-7O3nTX} zsxnl{`5weX31U{*4wn%A(C@9`IsNpfy;e?`mGLK*Gp^)(vJPz45Q$? z5f&w$UD(8t(*%Kl!gcuQVj?kX!PNO6RDy6Yli!zFw&jyJUfSn3n)`3c(j=h4l?Kv&h|8<_L8l<=D2(*K*zY+`A{fTfX`KakR zh2praFF}RJWkhFbMRfxn=jJt!oRhu45KnwKhs&WjR+Pdn2fMjq$sN*OrS>!ZCis4Y zTg)aE`RFF=nrta+_zwZv&BySCr_l6!@kfnMTLS-y`3&`km{5M#e`-#c4>}xT4s2Sm zPR6BPO1-NhO?Nb3oLg{XO|7ipbbFFyhQqzcZMl(m<$>UyI?YG-zzIx){0#T$j*xT+ zS^WsBg3-GrUig_E61{GE0SJ~7?D>DvS~D}1vm~40C_;WEjL!F3OHMbbKT2Jw{y3@U zE8wIdxdM~<@sL5wU^0xg_Jl7H9}58yQpI-IhxOQHgzVU4yUq98#pl@T^m(&r-QRp6 z`p2A#A`xU~K_z1yhF)fAMEBgP*#aANm>-90HNdnhS7~I8FrfflP|Q9%hKiPips@Y~ z3eS~a@@apRO>j$EBmLJnC4$D}lE`GYz&@^0ze8k9N0SX3Q`%Emh|E_xInKAKZ9^X4 z9qQ!*&Peg+Tw#?>VqVgUer|Ipy1pRs`Vmm&P%ixrpWN!h1rbm1cIcF2xLZn<($?4e zrZ~+zY-&CLAh!c!&DtoLHyfIVVrLYeXR9}!vBJ@9%Nr7U_!a4EGleC_T|0YALy%(6junaO+)$gH-a7C zi`_hKLhD225czU^A>j(KLf}{EilX#nhSNJsyY{N;6+c$18VAcAjy-&x4zs`^?Y0Cf zD`BtcAj5D%Goc6qaEtAujS_;>BzK_5b|<>ulZBUYF!S}~CF<8eaN~aBZdd9Baf=9p z2Mi$5sQXF;u;Ifo^oe3TL-U0ctES>GQ^nfOdQ3d7++L-L@?Jh^XB2Y4J))$$L9Xh& zA7gt(>={f@Ugrj>r7e zlZz*!7O*iO@$viUY@how{*;e6H80;>4~r)X5ZDKx2c;V&BdPoJS>ixSlGE=K3-!{k zhx;RTf$TWjwdm^QE%NG~Aprd|V<D`Ba5qW%wE3tOd;Kg zf^1a&RPXmU&OglD_`}~6DhiQ;_pBxhOqoI4@C}0MFg_I-_ZZeHqlxwqxGj~YY6{6J zx8~{#KNbG=8NJs}4oTT~II8)vTe)C+@fpgf*B(8xt#KYAK79+3=aI4kC}P5;x*Z{z zh=;45N};pQ*iG$atp>R&$%ye86g_82!1i7+)qsPxm_X||Dkg;!xi$NVhqg>g z!*?B(_PGF4otZlqS?U@6KCH2>zjc)$(36v_<2XrZMQhL%39&1F=g=^irbN7cMSY=O z<|Kj5>1QAB7GW)NSv`V$rkwoy`MXUEyBgC%_x78NR;tRV=aE0XiGr@M_87UZdWjV> zndJobd)4KZtC7+-DYhS<;J5Rf)Q$}|lMI%nV^dK8{t||~Gm*g((!%M7K?rnXTd^(u zjfuVMty=l9oK}!d@Vd{3`E?+5u<9PX{X6iHk z@f_Y~ExyYS<6Ewt3V(&>YSmJaQKXebiZxh>OgmVc?eN|INpu`aZC4>KvJ87@=p%sR zl{_vC!eMYc8k(#AOy0Z7hDUa@Z)5j)0FW+ToBWA|D;?6Q@Hs-D z^(LtHH{1iuKQ(O7`!%E|kQ3yc#RbEJPgTsPv`kBO-XrAAHg^QoWetmk%6i4W5Y&r&bom(^z4C z!{HP)69-%OMAj{x%bV9qr?peMR^&#NkQ4Y_{lk7TN#z#rNV>@(g!ysL_EhEFk9a9M3nth96{CLzuTqb4d63&(c&$Jd5vQ%p&Qe2x-0I z+MZ^{cZKst{poHH?WM-?Jz8Q7cu);8B3>Q`VN>tAJ~`<5c*G>MWAfO#usQg6#*06^ zMRK3=_NR&SQvK@q>66dD^jxagvM0@iyE55m8++~(m%N--Z+|hex^zJW zX_OZUhr+oEwoq%3&8)~1gacI{AG3KW3F_B)g zY2g!djO<+H0rf{UUks^7PLg6atUWPo`;Af`uL`7w0Ge}hJp;-zv~3yUlcm&?x?=9B zxgTCdB8R>5xi+BF5>8XJE#N0pf?*Ta-;rJ?Hkg>5BZ% zl;vTzYRxAd3LEAB2WRiW{?Q=Lg3)0)s$!jSK?r1yOO`h05a%>jtyf)d>rN}E&FqNj z5N}jEwIZrBQ52l(7wr;V!)YYxD6BYOOWb-AXTQ?I;0$UxK+ktLjCm4C`gqefm~iDu zT1{$2nADi+_>|(aQT3Lzz{(WCo_{ko%+q!xA!n{Y&DW4#O_Hg~M~1N?N4k&x9c>$c z<$yW}9p_5EL;kIJBmDh3zX>6;40j@a-wZF*+o<2fTVp)w9$?k8D2C98ag&DWbC3s6 zrAW^u8m1wf&{-!LwVqcb&^mvfS50$DOUlIb4^7($i%^H~HyZpm^N01!o{pGYS6MgVwigCn7TP3FQ zk1nbc%FA`Ew5T{*gXd>JO+n9kUnuD*pF891ZPvuKIPI!NY>(8hI!&lmLxOM*eT}>z z!_{Tp7jaIn!z*Mpruy~?r<_@y2yEKq_3}+X#laC2kq#2T_xLHH@fIKQyx&OXX%JNd zzS!Q|&c7Q2C)pkJxCUZ>oY+ts#K7P)c4mhsb)uOKFo(lnw-2wU#ZBnhSUK8VE%`?q9f= zCS%$(ZI^jv4V=&?CW88E(MeZY+RC4;W%7Yr_iTIL#h?Bohws!3>5dQj-b^k#W|#K) znc{*bN^6MsF{focCC<$ADEn0)0!>-D4LcN;EA4G{*ixRSqc>@4zbxh_*XZ-8lsTms z7g@r@3-CxYr0u-)@Fj;7;sy%Vh*qs-$b7K+5Tj6-aWw1q3EBTO*78SoPx@8+bI7uC zeD$od!Hh2I5G19C&qGf$#l9wdiu&&Mz+T_Q`(T07>CLLP9dq_ATjgu(0VE%S;K?6T z5a{^PBqvIbAjVTX0>RpGBFkT$UIPc=Q+N6*ypADX#QU{waUHb z_xFHp(~y5jW^(lwY+YIYhzl0bOq)KjgGa|$AmJ(NYxrNZHs`Hp*#Fv%)XJVDiYUW$@8ZyvMNhzclbFjYYyY41+u2449=9Sits zn%xqN*OZTL!eGz8q@aN}s6dQTM!Uy=!K|fdJ-RJm_cBIBGgYfbBK(*eC9V3P307kW z>xzs9E~5eDH=ab@NmSW?IfmY=`WC7>M7rOjjzP8Ig&P7JC_3sz$)Q6Yv z5_a2i(8@wqol>`K9o1|&AWt+J+vqOgY~xNj{RV0M4JZb|1*(zuhjTG*y<;GMTH$iu`OMi}{ z=Y|eyi-lp_q?NwMp}1-Q0#!t55KgdBfdDkHT7|xfrEPocRF24uI#cVu*Vh6|r4$DLHHRM}?}+Y7jVY>lod4}0()FsUz&ze}@ljwlu5Ti{S9 z=a8K9Df7L!G=7}Zj9m5q78W9m$!Tlv{mnfaOVkTk$oXAmAlQ*mhgv4E0M1Ot7aAC=?Q<&snnxgnO&9=~Fw^ ziV!mT9hLEJLG|HR5%%~82e>0RnSZ*_Qi7admNY_ddVG@4z1I9!IyT6Ul~9r1XWzHQ z0Gt9s7jX4L#`Lz<3bll`3(Zf-b z&7AkfAWx!_*7D2oI*_Q#ZkByOjo@s)Qk4h9z7C zTHB)Cx7^+$Psd?!Nu92^({)y*W2cH%8y`aIZpfc$w{Z%ak8+kJBD1xN}6 z9uQoa^Pbrz!FaJgYJG@Lfh7!&P6(8v*fyTdf^M59_JEul>+ua?Ed1mPo!WH zfeW!)&p198VBer8kd3XCGgmlcQdy8-8?aqPl27BoddcTRBj28Lx#(6@_j@G|$$3^- zfMNTgfMB@EZKXz5sVb=)t(aHkLjMqxqCrXHIlkqxD&_svkG_nPYsp5p7xz>B`!Or@ ze0IeYzCscrC4Ax(Vf6TRg6X$&7=K;Tjl#IY3qlFhm(f$w3OL}_aB8Ja`=ek*0$3B- zKy10RWUPzAXmegYTt)93_0Som!098Hg8i#n-agp37Bf=b_ZVlIBixtQ15Lk3ruyYx zn;$H*gOe-oEBtf}P$sZs1n9Z^TCaJqcm5-QzhI5k=O;5A;JyMzFD@WKesJ&MZb|GM zsI{ttpkUhX-YHGAakDC-{W(FrpsrhDIwmBMzVMg|UfM;*1IlC^tEh_>e@7pA-r|8cS5->_$FU0;!K><@@hU2;Z{s3Ji&*-s?%MK5=ns=)F;YUG$jXLQ+vzO!AWxi)01} zk2mC->`!P&$SrQEDS7QUaoaFpNLkhl*+}N~u#dnO&Y5BwqhlR@9w2A0o$1rifQTR$ zvpe=Um&yMmf)PnAy>}Q0!Vz?Y8R)2EetyqehuP(`pNf z@ps-h*>&eQ+wC^Y9E$MS;45XLYLZyJ*AB&)G#3@u+u$=!c;Q$!UGGleIe-^NlvPe!c(I(&%gSMl~l1@T(EU ztgmQ|W$>)}_F4UZ<^C7kOWzcRzbXg9N&{cD+8hhPDqXLLMlJokK2ZtogQ9u|d+cLe zh+;)PTL|GEm;V0UBihf^krOO&28xzjoB2-0=-We6HYn?@$fkxtgLK@LX(dLyIHz93J3ij| zg50EaoV^eJ&K3$Bk2ckYHZ z>#ntU2*!6?Dg2NG2hfA-SqacL&+%!Z6D90{IqlR>oUy(x2m=zI*0WNahsqnT!48rh z<7tlJ`xD8PN2=!&s5aTEJ4L+duBEC*bXWtj{0FCIi^1;_r(isFW$ue=v~GV!a!AYZpEIWxG)W6v>Q zUMDWQvU=C2PRv?Wmi2+R$;Q-2u&{hx0h+iExt)GawC9|rQ^kXs$492id9}|z098P$ zzob30%d@7IT#rUZvwfDmIRwuoLnFeNEj)|M*l(O7C$0RX&}`FHOj+~f8MgX_GfUl- zd8A|z306q%XuRJ9t#9)#T1jk!>@0tMjO4oC$her$%3*F>Cow?<+732m~QdUlmp8014Y!%_2f7np}A+J*oSv;TVdpW{GS4K;=!5t zJxbDI#PRB7<3?6p+v2{f578@XL|*m5-a%|s79DW*!foLRw`mRA7`k(q?)oCCS7ymV z@u4+KEij`!<3@E3Z`kUHsgWo%IZhGZv7O3W_G&oMayAH?63L=jbPG zH~y6>2PhB974a;GUAW#*r^iK&2pBx>;q4kTLE#!h+RWXFTN$#2^3~>Gz)1ADYi^Qn z=)X>7(BN=FHSiC%$%o~EAxU^T7nR(Uf0uAocX;tdkpG%twn!R7{<#-KMkd$y?2b;) z@PfQbsv`Q0vY{>Af+h3}9ze>!Fi7QhT~5cIITKuhq3N(r7zGs3er%bV?+~;W-ja<0 zT$UDM@7#gl0KKxiam^+tAS=5nd3Svg3}SdpAnFq z)r~h@x^iUi`8;o>Mn>ODD=wxhJO$XJpiRI0ght)6UykXWI6dBdbqvg6O)-!ZyChwH z+cv7ewlD(yLI_ZC+qSbBo3WC)3q!jma^uWepf>;x z`(JBRYb4q^x07`1{{?MzCFj#s6W5K&GF)wuS5t&awiK;h%!5nS6dewr6yh2qVUeY) zz_g2ee`nm#Ws~S|_8$4->~Y_-e;AEL*(D|`32UB>>v$vYaoCLxO26aMo%hhY*w>&I zl`JHN=(FRhhuJ0R6c*GbpL-=OIHWQ}!Kbb2!qzr8d1<)nAG0={X(GkBrx;$L1zY>!G8+1S`{N05<5*4@{Ddxrt5c{M>HSh&ecIE;Ga4&;0%-;krU%hMF- zw#2XyKxd0l`Y($uIcW-3A&$^ei+8`Ck-5+6iZbJ=m zhk#@wXvA4JGnAch`PFhm_^6G+XQsKc0I$P4ohSkT09t>%KtBO?T3-0ADV6Z9iByTg zBWib0G6sIS(!b|Y8nh;0iq!^AGg(LGHi3{oARRjVTThwtI!b24yDsv@WB zgcZdmqd)co*Z>Nh&nmReAvIpb!W=x^ELQRO9=%#LGZ93axZg7#&eZ8K?d4BDV)K4MTQ=M+5Nn3!{k0tVbe%yO77%f zC(K_dvEDx{|9F%lFo8$@>xjhjWNput@=S|o$H0G$A4`~bO#;OSh}7PnNERkU#kw}++7Q{6mH#!> z?9G43W)Kc z{|RKt1=J}XMbQpdL zKkk0H#KMr{b^S7`$SA|^D5J|#A#-=Gj-|yZEYKhQxhXtadI^@J_(mQ5FZP$3)q-as zAZGx$8x}GF>dzz4L_49?C@Lmrx=L#)XV|`@#G2_kLIbPlG|{6zj^tz8es{iXZzV*Z zKb|iCO>VL~R2?&V1--98Pv7EwDMJ%{TJa(C=J+f;Wy$)wf(~WO+E=F4k|WnO4%=S< z6sQy>tnF0=`v$+hAg+H>pQ3SmQa=}b2FguCovlvKHfD;eCn+7@k!49Mj@$63`7Y-^ zQh%lQAXKYLF23;E&ms52wHyUmbFR-a>|)d>y@d@cNMH#s4V=%QLp7B<@RO1C%}7<% zZ*3F3{nz{+T%=PSx#L^oLIw4BcnF%QM#39nqFI91CJ9*Jm7m{l~}2r@8D=u*{!K7zv|RN(V1*Vi}Vh+R%3kwqha7s|%* zc6RhYl`6UulvjNKZaHeV{EKM+=1K7u$l~n1!+OWJ!*5c%&!FUY5Fi>UBmk>D0gq*C zx4vCxYL(RxeNPpopB>^Wyb%eROp)KuX&mdn+7W5_jj)T%$cx^Z&5M_Xo62AoMu&p4 zKapki@VYD;h;EnNZ;gntT-5h=9w#T88_TE`Q1CN~pY>?^)=sery5LSk==^M8mA$@l zYsFe`)4SkI!z(PSJSS2m!q9b}~kOXQ)1U-8q|AWtnJr-$V}+!CE0m zsI6k|^+IF_k~L#_Uc}Z$eKVx&wU9qJo@_#{hF(dP22Cx+60>5~viffDyL9$hpX3es z>a`*PN(+i_nI0|(T2tuj@j2!R9PnIq30T9c&&KsTh!H;bkKKZ)G`zu$5xXt7r3^N6+ zf*j-WoGL_FUswxuy|siX-lPgGmW6E~RYv^+v{fR2={xgQ-@OzR_s?XZFYnn;Vcuiy ztx(ffI%13Q$g=9;6GtS7qQhd0@x&Y&<(&sU)l50_8xabdo_emZI3qz0u1$e*PKcZO zTCg2c;nbl1PF;7`xfTdR4V&;d8JO11A6-l87#lTSz5Ot-b4a9T&iB;j@)(gS47Z`$ zoA;r<5z!U=lKXepg}VTk?n2(`LJ-!M^$8EMaNBFNde#8Wq#oVSlQJdtIL}qdwDXZ>}9>31e_vFoNaNl4FEjL^tV?#3Hpo$17wgV-Ndl zen7slNl433{$?vqzVszEeDFd>+LP!JXhD3Pmh_{4X+Gii{#~>+5(9IAqs`LO>AJ#k zu-hllejU%7!kmSrtv;_HBjl$$dRk?FMn_00-~$Dw>by5H@N*7Fm~jP48%lzzbNG0` zZb$i}o>cx7-7_hCD$TwHt6xRX3JJ%S3rZgyP5FWi`}>ny$Mr6pb%s>Wv3P|IL@S&6 zrMqIP(=Zy+5`3mF$v_X z0EE$@Sz+iKwK{Z`;~1l72XV#2x*r{@?%a$-TS&nf%HH&5-DPb80>Tx)Ma6#+7`4pJpYnhoiVg7r}bW9 zZ0Zl+C3_kHwz`~b(IC1CDR4N3u>6Wo*5FfEffivpGAse&t9Y^ z=wn69u~EUdnF9gXDkx>jOiy&6GaX5F_GIYRE`LjiHlha>gDi`^%zC$Xs!gg?|8MIo z+e(iA4uklMz36AewsGz5=tdNql-Up(EC;Jfs=?0Xu2$Y%$eveCRWUQ*1@Bc)2gwUK zVyK>O(2qKLsKE&j;Nw&D3^CjgBTq5MFkmmpXJYr81f)|=MxBz_;G+}%ln+fVHF*2vvIqV`Ab_ZVNz>|8bV!6M=KRQMvXoa|LQ}Jw|6KUB<#vh?@dC zh>aC5ZL!4$5j1T$iUFgyFQdLFixXX5s2V@JEYuTYFU&8FLzm7yBf_HzbR|=)X+*m& z;{=<|@-K>qh!m*>_JTO9o_YNHEF(a4(F#<})YKn|Yk2F_*m}KtX_J~)^FxYJ#6%Rt zAF0pajsfG!L9u(Djc&4k&zom~2W;DY^ZD}S^I|YN%gdcs9+o(48AYi9Iwr^k7;sCf7HSD*lFD8W<@o(NjQ|0F_2<3} zJ|+)DI-|wQ89bDUN!ZTaFm)=D!e4n#lq79;6tY0%)UgnPC(x-|4K&Pr!Du|-uVKUV z+3LxN^q&V_2cco2Fi4g(QY?Z_vAiY3{b5^^*C7(GFHD46~Z}l7%K@-RI)G^2rdEui7PAdLSRE!1Q1BHRZ)C-<-i^M zxfOzNcD zHBNGED-iMo`i`ca& z2bP7LU}yX3IgVS+43dJOUohfpbN5KF@C5A+ri_Mq6T#2)2YziF{X?d8h9f%LNL!=2 zW2*gjym>TpIC5seYRos=hjP6PliS8gLd=<)KWT&Y)~si_e$ZH`8+!P=Gzl^PhB%%M z4Zz0#79DK#jbi3Ryd*y5Gn%AoB$udos@#gseudtzOI+Bh?^Pn+=D5RKRVtL$MK zll=ru4kmM<$9KF#^7UL*utZX9ko{T^)G#h0e}BiYLjeNVS-^%hhFIeGBsXbX#qo7- z>NA8%*_jm8_k?>2dt6ONbosPlPtn$Djj4fydkku{knjVUmt47D!4D?Mmu9KBY&o;y zxyvJYI?I0_mYm+YzujBp0%jdo?(o2Wt7n~s%+AhF#oiSg9#m^w)wZotzSTK87YBvH zb9-H;G;qLILP^u1be*k*z~I~<{5PNWeK4T)5bR$!c4S02D&!et8IbvpFG1G2fYmYX ztV{INDQOk|DZ*wZMc+Vuem+Cy``w-0c^(+n4;zN&ZgP>+5Ik+4TWy)09y&9$BlbED0WGUCDbQL_uH(%ZJ4OS)7c){` z(5)_S!^dt_&EvTt7zi&zRF8`sa6<(wjGdJ04k2!M3XYFy*jzgsnEwQ(bvJyS3_6Ob zkj$=3L3H>N=4=Dauh3fy15g_W>W1WX*ad%goU1p&ypUF|mG z!%I-1i?H39ld$~t}ioyWh0!{M4GkW#apEKt+8H{Olh9;ifH zxJ4)N+c9BvPO1`OPKIKO>dR*S>26-qp_0jl@w3D4b6jI)p@zTQO`P`J-DZbd!Cd+l zXMKoCxziX@S>IHek*&yKtc8hD{9w^cXt2=425KtFrfg%IJ#j7@02In_lL*^}O}5DD z3i2biFHGf5bCN(yT{8t`74LkkW&^oborvr@l-T&LS}V z^Qg4|*fRf3A!%hkA^Y}o#!gWilqsgGQpZ3G12!hLuSrI3gULAQxr-Qiy@AC763V@X zM`m>Iq`kI|fVV_3l9$MD5vKU}>mnrs+L8VcdW2wB{3wI?# zKI@}AjycB1Ig8PrPn?v4Gs+|1h;2EX(7R+%O{_$$(Yd*vnuDJ6Y)~XNh0gv~Az80|pC<)|>bBgIlqSC!y}fN`-*A9}2$#0u z=&;E)UXuSF!}1i~!{h3Ef8ehsTsw}Npj@-Q4SBd%Z2{)^>53kit^O;NpNqE2VS9wq z$CsQ*u6bujY)Z~{ywmQPJOD+pLXUO4y*iWpeTa^#V@Y?J95-lf07-3*2lNl?+&@(y z05TkQjeh==uB$4RZV>$;ED{vwcHNk0lNKOLNC*1vd++ey9dk1j+t)2C=-5^64ii1m zszXOyH6>!sM{sheguVpAJDLE`^rm%JkOrnsq(`MQ-m0~u!$;v?5vtzac1h*Rzu=Gu z@aSN?o}vwS*zKRIWvpJHcIH?R4VC828p7+f+|u)6#|ob%6q%I0oi;ja#E*I^H*oNr z!sVuWWa40_YWBQToh56zX>^C+M7qSE#F{zjGZC54mXYz2aMt-jeyPW0kJwI3z&y(2 zV|e{R>bOHZ>zg4PErv)DUr!%gG%87R*>AA!5$ z=!Aemx=(k9V?WL|?g|t=wtH)dPH2(c$)USzGneUm~NPG=AX2MR`J*JH; z$GOFb!Y%mW`t^TF>pGmGq5w-ip?mhjX&p{-;1Et8EX`fv>wDHIqu-q3N1x+>V2Z&= z)ECoLT-rtTG=sU1E~fJx;#mLa(GF&TO^q5JJ)WC{2cr;K9wG7!fR|Z(APzPb38sd= zrCh}=R*}n1ky<P2@ zbi$e){RV8`L8*OdfdzO<#RU`POA%*6UNg&2aD%{RAp6oTaZhXptTy&{;K}{OOSM=x zxdvgjKz-}w5&<65e*KY@@a_-Jf$haYG#*DN!>uE(W2b+Vv|J!GpppD~>GcQam_d2oUG8 zy8?~G1s{z$Z-k$PNCL-SBO}nf(}BU|=BAyXE@WgIS?49SSqk3>PFzy%-yM7J$l*KVVr;@1LO5N3MhV~*~O3NxPU2AC`gFA**(mVh2v@`GBKBJ&ShcC zy?RD&`A4`L^ZhBI>QBtY-*&82LI=0dJYm?{!|gyZ9fK2o;x_&ye6G{oh#?Y{Yy6sM zt^sjlWMWMF{^G$YKC!Eqve?B1(sitegzFg z*Bp@A=rg?}rpmJJL@=^l!vdu;=l)M+8G9cH>99)8q1Ni>fIr@K=4+}iiF?* zMwWzzqsnLL&ge}7U47<+YvZrIXcxmh1VJP zC*;}o)UT9e7nkUIN||Y9##vMI4CwkHe`{5-FYar!4hNS!{{j7(n2nc27yfv9BXP1M z3)=QeWLHy_P6?vejIP7af*YsWB?vNR#Zk)R;74FT`R)xM`I9HCss5SLDZ!bpwo4)T z^pn^0qZwJPTjexgJ>5X-4#*JAuh#4SYhEcY$R6X@Yqg%6!(NpHu(5ydVqBRZ^$>iv zspNDXY(6vybIjVWsmXXzX?ZN_dLN%|TF9Tw>mJd7AxsVWX_!(3r7MH!9~>>#hu6i9 ztz~$j6(bC=hey-g(!?Y-(NqhERy*ka4$mexAyUV&$ z57cJOvD%bKWJhQ`6g>5tBp=^_5R10kuC2pKF-$FzdaVe0-14Fd(fHZ(2A3zEw1_|e z=A{A}xE(ySF%L7u*^~RV6Wrayj6n`|US~0MK!AP%;y(xw3ZSX)s=f3qcBZ7$p`@Y`$!!bgO4T@t&g%2V z+S<~jHl}{fcP=Efy2cTQ5b!C#6vn3BE@I@Dq+?1;O`_en3AaB_tC+&OdAh_8Xs#Bg z>%iaAnJ$<9&?QO74ln3abU4QDZrW?HrHy}ta5E>g`I{S`*taH=ufzQK}0cDZSRp=qGQG;62G4x2?=K`X* zwp0Bs+aK>%VT;=*YzJh{IGg}1RV;2-irD(NLN}|j^^D0BsE7S&ciph`t||JYv*zbM zQ>`|mQ9NBDB-CUDyDKSutUQtCPwTkR9^`mPQb+Hqo)E@IW98t?BAx=}a4T&O-Wuo0 z^QxTWV%1g$;(M#Ea=d@L0ByaL0j_x*3`>K$Yf?;Vt2dq;mZ zmaf($0N^s+dA-izxIO@It)qG+BLVuG>ZG>}I)!pUO z%4MnQ)zR?kOng>%PX#Iq$I0(TNwvPB`-gZ1`ZvnO6k~AGk~@%Qjzt9~2SMNy{b4n<)C8dYoMBk;A^%zx zB8P?S`OK}S+C+pcdAR`dd=xUvppFI#P<%osPJG_Qq&NK1`5(y-esTQO7;;V|qY!y) zLQP9W{6<7N6>QO>9?&Z5NpJ7F5>4TOXXXJwV(&gc4gsEb;uqbiNX`sDRV=4teM*1= zEZWG2q1fmYkdIkq3-dBW`bOT^-OwNO4FAldD)U(QnoOFKHhe$W{t=`9BxS9(BNyJd zJqZ53nZLlOMilmxzOk~u6Nw!FYG8mcpo7COBQNz-D<3Gq+VtRUWo!X1Z*LCY7_xOv zHk7wOc|NWG^1CPGgEVhAqd{dKSxa-j>D+5YCAz9$!K))q8q&Owbb?@nbt086SiFZ- z(7A&&Ia=3ATTI@6-skaPG=I~b02+78Eed?@Wv;14D7|dMw?v#o=XzRN=GTbhmp&4n zHw%Yy+Qzj|ii-hYj;_d~JJ3f^@A|yY_v;P^lMN>~*I7hjfSNREG6C_umOg!j8gp-V z$TyFrp{gE3omfMY@*^J1sZ_s3dVC_OaXgGWLZxkTog-6i>Tmb{&V|!;v;(=$+>I%G zwbsy8g?Zi80j^#TRlP6^9N(*3WK=de3nhWY`5jDGg8T;99R2PTS8C^YUKXWP(3JOh zkLAo%H3rllB;Hom7LEUnF%u)XWCl*RsRiprQ*^ubJ5LKfC0y!Ets1EyMshs}&j3^j z1{P1kcNuPk8LRh6BBCNrg@zZHyL#tERQJ(>qYC0`qB68YgsyYM1DM(FIP>T1sWuf* zwiI;61dM#u;Vne=HJI>9kp5Z8_fJDhGm9 zsAaF;;-r?`I5ds>+e!Rg;(HC6x$VRT`zx+dQD%^Y`ggD`kGZz##Y1Op&vmrPElp+x zl2_&et^-^J(o5{B%+Lwz&Ez5-?-7S4K7wg{jrgCR;rq$8H7#WJp5_s zNY%C*%)HRx?_JqVk%c1NfAN#4|C&?@CzI2utao#3=RN!Hmer8xtpjV`cnA$$~LGQXV~SXhjI1kN3$!I$M-5(YB8*4*)`ofT^*pZ67_ zMGi}6vc1KvCvK(!cXsOAx^|&(%zS-FzpW|tl)LMzK<&rhW`w($;QgYVztN6BF-`=2 zB;NG~TY}J$3Aji0RF5kF=`PUj$<^oG2KBo&qmNWW=TO@qpt7hz8a?A4PfVeicmP&; za3UFk>e*GfLN9 zEVj~fk-+}o=I`W=znQ@)d?(+ofiUB5ph2Gq^ooyPmm2?M9)zB5o&sRx8qUAB_mKjI z3@{;|zWy^+v&5MY1pZ3Q@>y!ZF3U~57>kR~QDxqON1r~bX~3^$xi`TUlIxPY9Y+&7 z7C1&hnSx;orIzRxly$JXrYo#wa1~>vsmJej$c|#GR8s%0{M_BzOPk&4u6yLHKdHzF zo16&$fqmH%B`0{)fkKQViSX3-q` zgP365HTFf}7&<%D2Y4JYa?8>geI1Wi<*8y9u)ipVKLC4VzHajYAgf>^FC>!O02AjQ zj~V?BtSpjz6fSnbtZ??`-{UmX)$+=j>BP|pZRj1UB40wL6 zxa8;&vEmHk7}4qA4>WyD;)Tj7L)AF1apsnNR3bf#yGJ?*r@$#w26?-u+3O*w6#kG> zo|pRD&R{|bvU5kbYJTioKutCI47L9JRQcc}udkaGE;7=svt6!D2P>*9oCBy^w9wij zQoiTRSpH@*;zPfC7P89(gmWjc`e<9kAi`;fDjcy8k~_tVe4KkkXclEoo?`P%8H3~L zgi`o@kbyl|dm2AB!(h8>nUF-}Uj^#@#WlK% z%vCA0xT8+)IctbfrN<39`J-s zfuxx*BTZcszkGDY&|EYRj=ya}!HBK5z-Adm{>oUI4$a7 z<=J6_dC7+zebW#&^A(D{Xj)mQOcRo`Yh&J|{NJ`;ZE3bR!hvNrSTksTneTXDXT1)8 zS29HU{)>WgN@wO&Hk;G4X0kVkE!^}0WnY9KQ>aOOwmS4x&}`fhuo+^bxBc3@@l(uevPy}&kT2Sp#d>&huW2-2im{2fp#qH6P4(?AU_rogdkYn zzooC0SoY|sjMdIB7Z#vr{Vk33pq6=X*KE@(UyBy#?W60K@Mx*=1y#bJ=TUOkOSIoB z<1SV=r@j$dwV;S*cJE9jvK`0jGcQWB6fcw_rVwwh$ni)-QB|BN#Dk-u98Tho_^luK&I_ejkqR{H+yyfIb`Nl91J zdmo1LUL(-b<@tBMwlUpReOMFpMs!d&bq&W@K*@E%RxDR)z=2m+Wif!%=gfqFS(1B6dA@ zX)B`vHNb}#vOSv1Rk5VugZddZq8o%~j|JA820H%P(Q1qu*iM220VX1#L5@A#_ug9p z7K(HFKS03#Z#jhzp@54h=oF}WUF6hNfi$*m_kl9YveeVdo`ekap=bJ7uZf+pxJPEh zU5)?Ir-o^|mn792_Zof{KKDVz82{z+gH8=}sPUTeu~-70d#mm>rQUk4CCix*muXY42rTP^-0$D$+gZQykeT-PyS6#f`!WHNWzv!57JK}Y2RA=#Nb)5#MHkkwm`kfeEyAIV z_nn8U1Kd-uRI4#G;n}6mmtkXbkk~oa7dh+gXAdVx_AUa)R0{WUzFS6hENb#TEy9zK zQFYQ$=|4?WwKgWMLPf#zYjnll>Npm7E}ws92md%Rht>|b8md{^x_p}n1rj4G@`KUI zCW`#Fr>j_}=x0?8Uvj*`R~_0r`+PR>SGW!Qg*;*;-i8{ z@w6qN~%JG6vgskOx+%<&-u}n-+^c2hDb5a12DfVMsaZV z9_}7c?+|-!AitF!#1S-Fd+5mjZ+YqKU`$eC;$@hB0)LOM_rlm#ja<%jkF=I(}We3D~MGGq=)LQ^U=V|ov&L?Mz-jHU19_+ z>0?4vwI@`;Tr__NqrUHQono~JEYNKLtAZZlAIN%}ssOOPe+bdme2!~2`WCI1Q=sd% zJ$xHKCnT?bq+>f^VaLUu@pFGPrNDT^PY&q5yuD^h>sE@rPUZG);N?P9fTGHHY$f5V zX;(@+rXGEJtk{zu!wnxT=-h4bk81X>VCY_F>I&V|7%Ct~VItEt)21&u0So?IAd=hX zf{>(=#~hi$=z`EFP24o{`*<2$ zS4U6eF}vkcny_@7VoOs18#$%)Z5yHzeS!HL)k#C?b5?rRmH!x>aHE?_npsEP|EJDW zj1xo~!j$A?7vuy*GPsQj^>{rTU@;~_;y6;?FZ6^-Kb0~0FmG+~;z+gRxb5S6H|I^; zo;|3QNq6gr-{HQ5hf8yeD$k`Vd1Y(Pl&1E=uKn9+%gO!uqpx!vC>0n}SY-V(Y{_&w9Ru3RMTv9E*x=F_4t*~ zfCnf;5X|54Tll9J_wWG(CWyg8cY}gZAV3r2ixY8VAW>t(s~_KS=8rLjq?c_P3)CuK z65i8CYn0C|#GmDR6L2@mSx&fPPXC53DM`7q@l1hmjKx|^aK&{n$xDqqtEC*?Nqrxv z8UJKXQ)W(J33K=dU-rY4-RdfpnV#H|Pe4pLy&N(}7{&Tchi?MT0nmnM`gNq;c&p^! zmSygne-PkH;3VXGq~y5d0ClI+gX?zYTyAbGiX*ofW;PeE$<)f6n;ap35%l6}IDWX>nm z)XxV=G!qZaWvf4=YrEuZW-({=mp5ga_ti+k)3N3MoC!r6s2s%H6Ld3?NQ+xPHVGTc z=e5|+lu+XyE>1I4ZJfA23>OOc3EY&qDHriTN`PcWj-TGa4!rD+Ok_UMa~b;SphFK| zsXcNIzu9H?j?R<*r@OoShF~vt=6pa`11&@s_ce3dg@YiPTX_cHUpxC5d}}2+7}Kdq z9iD=8Ay%wO5im9^RtePHe|Jc1TU!6{mm4+3A}8&=E@jXPmI318+IIi2b9lJ;sL3MM z3+IbwoU&=V^z;c8xoOVLp)Le8F-iq+{Q`t@gXAFW0&J0@j|sH99P8H!dU7s3>c8~* z>tsm)fO|nH6eqXgE?S(D6llP0XPAvLXft?MO7O#(v9-G=>3gRag$BlNRu9->s2X!i zzl-00q@5)5Z|rlRQ!EOr9v{ zh!g)jR~tAO-8x2@?l4;s_^Bg5NF%iz=d9fVm0pcdBS@d4PGgH zAKiP@ez=n;&{H2KZy9&_JELOh*8MKd=pO8HeqHc(njuskyZ~Dg)jt6+KxpFgp)QRE z(Gtz#6{P1n9;!pVY={&D>={Eg&D!b25iBUAqbRtr@BAbe;Lhq{U-rp6qbFx+fM8P zyi{0X=;<5|zLVL;mCG+1n9QISo5!U}^aw4bu^)YQ!jF;SF2Clv>8^*aUIDh73p$k8 zeIL<&b5avKk*MqOgI%bL+r2dQrxCQJ|7ppe1ZIv+oHkBFG?En8sZ<6ST*uq$zIs5+ z!k4~Wv5ipJ<7b;tyWi8~+Y+Ef-#tnpiGbjY8_H0;Y_P2g zbSR}BvYQ|=G&5rF^?anJQ*|-Em(n_YIN5ym${St`Ci4>q1l!rzeesLohX=q?^^ciY z>%BPYgsTt8NG7xn;%vH;P7MV52>-Bk_q9wMQS#dIEa>-EK)-nk^kfGjah+y}rQ1MU z_TWQgUe;U6w3HZ-d2}`UzK1<4u7;srGF|nnk{#XTjdfmRzX+XHeFCz;t5Y!jstFDI zD@!F%=dS5kY+(`~Ds~4MtR9f4^8Kul>C*#eIo`roHU{^~_rxgG1!CR`7QnN_dOzfQ zMC4p()JhkRBcfaJ5d-W5M%bG(ZTq(*$0+HStb{DH{aU~{}K89@=LSs!kpMYilUcX_7HQ9b&UBE7Rs zrVBAY?Eg%&(=d% zdg!f>@U>O$Qn~8}y-2*uk~$U+FL`%wICOQ};+hJK36cxu@#uM1=%ln?LmW@j5 znwRTT5~K=r#kj4!$@cSzB^*5mF|)awH&ilTgpoO;$~Ji{unk5b^8eSpwFU`@)3@%ln zatURdlOE=3$C13!p-;3TX9|wi4=a~M?~B*#EoN{}XN51Z5CVpO9TH1nHA>O8O}T_m zcGx+o9xs;Y#!h4cVC2&KmLu98DcRV8 zJ@$Ipm$-Uxczf#a+U&QphT6`Tw9blb^(9AD_B}w_|7L&GQbWmY>yk(lWeX4gFkntT z-(o>OxFx-CS*EvlwVnQ&>X(#61Riie0uTV|yL>w$W8ULTi3l(?i2-oMiWT`s3=!g=^P(PXdgMHcQ#2HhL_~LXrgpxDLIFoC_KUel!`&Wk za$VajO=;pU;%(Cv;$vHiMA>DqA@bydwQ!A|{08u9(JPF#Z+gCh;PRQhb9R?Fe^iEQ z0)U8u(^$h^@bV(E{HW(zmc+<$FPqNdHwv}|6x zu)_V%vv?mk9fUNlcml!3e{9FkmZY|aJ1hF;DP$2)l>A%#3uVOiHC%-o*Lvo;9I<%1 zS>@%W4wal8AKOhs+hMVtM5=u5*rD{T*ia8TvL#Zte?zx%Lh;UW7@B`sN-#`Ig8P`ZS$ruikR;HIcZrx%`-r*y?)KNd%_^Ugfkpv=k-O= z>lFbNVFfPtN_0}2C$NLOf&J3`r7lRslT@hn93oi&uz)Ubas1N?30_x?>Y^t6)ESO(QI$cVI2Qs=sPI8{FHrX|9o=YIvmAv@hRD`u^tc z@w`miVg21l_dP-=cvp{j<9JqjR09M0?@ZdP(9c_4E=E^VUsg~!K}`K48GW6K{1H^4 zJcS;IhNtc^mxM^V@P27I|GWep)1OTfM==O=D$zoM-3oG!!Zph8)%Bm#@w$N}!EBn$ z7ZWGz2{q3aIT(N24C55NC}GbOHlA@3=w$OM4(1Z#PVbZ z)1UR;Oi{h@!|@)$JPY%s4-j(7lrYqg_p-IrkZvdiPdi`x)ZRn+ty_Oj7@*)Gy@O4|L}5!{4YTR6f%N-Y;{ZUm&qq0Wl7ZT3JV2oz@e2 zZ<18FX^xwqeip)6zHM&@UZeG|`&q?Z;wYEQLpXhYc%PxCN8?2_+FoSkbxDM)`IItx z6L=_@DC8uZuY@3pWhW~dpNU= zp1?{;ox((|w*L)2+p)Rvc;$Oxfu4@(k7cNnD%ZmCZXX#LIAsge#wXTtx`r?w4|Jw@ zR1$~Ks`(?ml4tqv>JQt&QnwytyfO`dxE<~X^tIX@Nlv%~aajJ1dD5?FWR;ejk$>0)ZJcbGnUazmt+<0D4Gz zIwZUlEeS4{k@8KZE8z~hpJ$!~^y8rPpBQbKwoFc@m|8GPaxOm+dHeS&#c8t?=uN!$ zMaR0rS!qJkd6h;|fXm88Z!`WxhuOBGq+ToaU{$Ch>LUDiVRa}m0M6Dbzj-11wL_Ty zlu+=7p_Y?g!!k zrI|saRhG{NScL?=Run4&p$V`uS6C@)1PC2mjfL##wtWLC>NKT}Y+K3|*F~Xv|DrK2 zRm|)E7j^F7Mxf_3{9#mYQF`p?u~0`=Ky@_umgr5ZBHZd!lL-tOX-Wvn@v05aV4Kc- z^Cixs^(^gGxEL3V0J&J^1UO68wE&A|@*$AnLWo^htR2=B`C31&3PMjPZPdSNB)t3# zB7qjc8Ua2m$AR?zu>|^a&|xBg z+>6TOX0$^lu>%1qQJoClWRq;tk&h;YRmn2pEi|DHmJzBsW!NjzIyYN`*JPTKH_`4G zRWd4c8d=$jI@k5A{ui$5oqH`E9^!J9nRVCK#)o9jKeCth9cgHh+XWjU9+E`0E(h$$JGhnqB(^8{=xWZs69Xk>F0S^wQ{(shmPFCt5CFzcO3?=7Qflyp>}zfV zbme^6SXd3*u0mskn00@ye^o{$N;2~qq1WP@WM$zmMRAH7Q1yNU3w~mOSlV z8#n!ndMr1{O>*_3JC5UepCVU0)Rx9}5$;J$*rvYH-NJ@)G@Qa!E^3zds$3c%c-ln| z`4Ic zqH5{cb(6jKD@q}#mn@~(L83IuL*0?c@tF@8GQ)PH9GsQ%-nX?tStarWF`<&Z<6HYC zhl{|F`0W?bpsYgFR`KP;o5@Y3AwbBexJtfb_{tq%Bips#G)&OEHh@Q4WmHMzxG5kR zj-Z?;=+m=#{u-@mP;rA~z9!iaXL>7H^`5UIH4dqJHxKuwqztRJltG$kPVsrx!@U46 z$8z+a_m5N!LLebPu?_@5{RNgyO}pT4Ub~A=Jj!p__fVtC9wAP!0FtocdM?N}&mZ0R zeZ@*_SKq-zJF`$YUe6k(fTa5d(R0$s8y@IXf{(9e=&A+I7lK11)AN#JfeHRYbQet6 zZGx5^I_&^3tuGT({Cs8%H@B!@lHWAf2}XZazYn6pdSUCGh&$2084*f~$;)Qce?J`z zoB@i0Z}|iH!`#UN5p@_!|${1ZzY4{M~{yMplB1FLBrBN&UzjD8$4rYKw<$Yw|Efj6xdU7Ja!3_(muA5$aqW9l$vB+%m(T zygG@+=AVf6bKhOLv6>hr%t8+qgIkL5vT=fQ9Paofx!%ETldJVG(cl1Tt#{`6xrFtvolbOWav zHmXIkXXKFy#cUx_3M#`nZ3=sIM}Ay4dUlyh!pxIxm8m^4p{>7+$?=8LIAgAduOanT zy!r<{0!dd$@Z$_ir2{6lhPpzNc#80bDM--7)4`G>?~<;~ba862VX+$pKMcEeiHBmkJK z=%|SB%UJ0#0(a1~&-+Yryxv_tG|M>_BIl>|TIjhP5?#9#Ea{A3>I$ zKZt7d?3oE*V$pMqo_zGpu8fhtVu6JyLBc&IOh0j6eU$ANX&~kEl!S|@TJ`_2{|j-6 zOLlGWcPv;o4aTRkNB@`pj-n63cUYUA5R|tGb6c-Lo6eOlR9ymXIjEh4~*FH#Xd)EbTy^E+-Ryx&; z78R3iOYOlD(ev;0`BN0-JTGZSVp$@sI~*VNPJECnQBFbb4KKF}`R26PjyUAgDEOb{ zOGQeCuq;(0ghxA{(xqFAXU>LfXgA)2bleO$YwPN01g&u;y~b{ydsXROq&>1io4duT1*#T=v268TyegwqWmC8y zVNRfMKgaput{Mb(I~(f;D0)_m^$rS-BS`pyU@x+8s(r!K4)3?ZQG=+(gJ+lb=5zY( z(PFzAIbhTj^WhO#+G$u%_x@4vrOPYNqeS}9HgglNA~ASZ)(d+S34SI=-<5JfK2VtS zByL}Jrs{>_u$sRGOmYQ^nB3ybGQWj6Sl1^<-oj1d@=$$5#Q~jBbJm5~FyATjM7hy% zZzx_ybfhnjBsm!;nG2NS*4OOG9UYnY@H_RYlh6rm6oS4WjFspcv;kP}i;9PtN6oOf zlF~u3TbheAgw(@wjhcQ!YgMSl1D%d7>I5R}+KmaGd5I7KEuptFi2y0y|GH0d$r)s3 zc05{hXgBx%O_7h&2@D*xW562jmqkHo($+FmAT=9v!Dfq2s9YRR$}E%QNJ1cZBmS`o z@DAJ+rPF_&;M*OAI=mqTuJ?t-$?GXI?(6O)Z4U9(<8aB&F5)Nd4_v z>Qg2xAnDoXm6nxutmRzq<$CZCj|@&%W{}0ys-CKy!fIc$P*O##&R6&^0UnI)H7<(0 zWljAXzpoz_fb*LwKforvI6B=suPh~r(jf2%b5%rEpPr+VJ1~|$d`Y`L3pp_;7%HU*-a4-{T^~E#2fIghn%*%$c0$Z*>Fn?3`vF-f|&IRmUi!q*f2e7;9Cf6$q?9J{Zd)E(O_tM;li4bq{`l z_WEFT+YK#9?#udjGsSG#ohMi8+kA9|>V8GpUjaQJ!s*Rtl@q1i3|8W7tof82Y0?uF z5KL6i-y){uv*e}3>&R)5I8ic z`J*B25vUyG(^NtfFJXztZA2_4#ggLBzs#bukiKwtk~C>vycH|iug+P#C|_rQtGbON zHPqppCGsmDftKZS)rmbA01dFy+q>O9(DqFLHy~<`@>>_ z>QvthRK;2rkFR2b&{2A!G&LNRAkpC(mgH8xZ#iiqU>vYb4-5;jtBo&mBf!H0EhvzE z742!!*}AMG;){cp=FGN`*r*(5*^}FQk4`t_WSyU0>)N8 z1W@y6XkU8yYtfHorv* z#ah%({OA&$0mYpNqBJZ;|6M09mirDKeZ^;=zNI(yt=}XT$Cfw@Bbg9wMqMl>q`l$~ z4z6)JWM@{`?=BdWyI@ccZI>3c8R|?C2vzhR4uC#Djkm$JkT*VEa)^GjU9Di0i|KdE zO2lBXuK)Af>;WUh{%m75VO3_{X*fru3N5R>)u3w4(lOS6_zn=Ge95VOt-5&L$aBYo z1t*RLEb9pe4OuF(&P;282@n7^fh4U8U_d@XtPMCAeiCb7i<5?fnm!E7EfCI2b>yx0 zN6g)JQaFCJ#hGk`YB^V`!~XXq)zooTi4Ig;7f4)c7> z`^j|Bg6o*R8BD+9Z1VbOo^DqZSKCinz%}bF-G6aM8CmsRN9DJs=k^ML09FEe$G`w#f2Lth)-D+FM zmS7JHjbFJ`r_TT+0Gwux`*k`bsiItZ5lbW%g9oo&QP#5ZWM(@R1buVzt-C#awerc3 zCl12AanWMd0Lzf}0>pL0J-9cs2K?W^I$C_Li7Wt>eR65E63>lgXAiX|fvdtc}+18bE3GKWr$9n5s9_?Q-D zfDmmB&q^MMxVAn3XPD;pxw^p2USQasX6YZs+*u@@HF8X|-?&J{Y3l*$aDc-Sf#jRR za}oE?`UZmsUdeG-{Q$Zg+z#+W{SHr{(Hng+W zSy)2f7)SxFkoFMoMUNu+Qr%;_Rg30R2xNE=o_01(`hv0WN0b$1XEjA&1lXQh=yMp) z4lJT`zsQotEgVxCb^a)0x&Je{RrItIbXTF~9WJR-_-s84?VPc;!2KHLw&hOX=JQ+L z;!bmMUGL~3fk|u_i@v=LI*?E4mGbYE3*lvx(o;3Xh2YJvsJ?Qgbq&__8xbM+O=;jo zx#34p5G)ejj98iWfGG-OS}f5rZQs?&E*;f2J4M(0NSWYNo(xUd2SwdWK1Ci*Rt4zl zN{PmG%KNHSc{B#*i1P@_Aaf6sL`I#EVqrJ40(n9}XzInH5%oA0nz31;Kxq*57#y<8 zCvQh%lX{!3-lUduy&Zmt@4&CqWe}mAE1?mR?^mSAP-i$R;*&I@2E?qrEV0T5QSSjF z<+3$b7VJCYpq~-~`&W5VWi-U?NoDVs%{+dxlNS?3%2#D}+tX~-s;IKNvf8ljKS~^! z!*N!oyA(+kh2p-tv~bN6J&JhX@se;VRmh|8p8#l-K`qYs^t^Hal~bQ^c4a;L;Ltt+ zEdNy_amDk%C=HE+qWL-wc(B>SmR*j98|fst5M5=|+}L=sT@b@8yFCBgA`0uR6rW}_ z3p$5ggu`K!Dd&z4_f3HZ0UFQSUh`3EO?DW6s>jtAu8|%^$Lr z^DFYGRKut{UyTS&Z-CsB6?$y?L(JwKIo>Vuxle1l_R7rFTqbhl=x-UfcQkYf7-#zt za~08N`m0H%IcUNZc#-iVVOrsh2roePvWw_{cozaxNV#Jo=p(mH(<_|{T63I0_(1^6 z*P$jP7k?>oQ6mf=%VNC!Oi4<+fxs8uOHHSbBB%g7_r0-1jsC;0HhzPD~_Fnjg1B*@W?MvRO=-yU>xje-Vq&w z9S||T_+4*(i7jDZmIm$qK7-TBb6^muzR#|q+NYU@Vk zd?oh+tiMpAYus!E^blM7tB8f6ya1SuXn=Gvh!6_GT>Q5hS$Nxz+ulEZ$kP-4+}df2 zX2m#0+HMuxfe6mv$UKuXOf)XC8<#haoo4v&wUmtl*V*Mse*sV8$92MCHtq(w4)dg6 zN)NB%AbSD!qd=JnNT-{E3?&^-i)uzPWkg>U0p#yAxse^cI1=o3ajM5$tb^_s!*{wr z#c=vQAVkve$Tjbu8PY9W(pN{3TGinQ_tITtoKv4$h*A0zel30o4R1 zq8$@BR+q(Bs8>Pvm?naSR+U1}l+cT^!Fd^byVZ~IK%yT}VVWpQ53~v1^Nxq9w1&## z3XTze)*UCv9cDmVM;8?zI>{N!t+V z5F$=<6lxZj^V?Gwby4s|;#Bt;l9}nB=-o;cKmAkBvO|&5K~~#sAzQ~p2Ha9R_ygp1 z9M?)rkB9js-ea>D2w#&gSdST)i~+m$7{ug2dA+0WLimEnEgh+SI4nlf|IV)pph=)8 zplGbgZHS_m4LtVirTX0hxKCKnD52USZ>Erw9Vbymxy{%O_LHoCsJD)LLmG!-HG}kS zZk3-D)^n0zVyv3Li9JyJ_&$0Ja~D1?pwzdZEbSH@ZEBKO<)@`p-7|o zaLCai+y8&&Pqt_+^Wnr{YU5riYvTX_!~g=r$_OyW-pVzRW@BGsbV~yb0_b9F0ir}u zYMNrf3}bIo0aMNGHHWFvATwv`o7{BW;x(D?{O7@!lEU(VxcJA{nps`8p!pY>^yV!k=>P9ztlu*_I=iOwt44QQ*wy2dWtyH26R*s z;2D5mCRBjb2B0~#MpAd;jN1FKV|Mw%^=gbTF0O@+=OkJqIen+9kOD-G2t*0U5ctp_ z!*dWRK%GpU+s?RLtZ#a#2f{;SBAB6juf0@%H$c$r(Ls^)FuO1NbzwkIYl&WVu%POKoU)N_< zElv%MzL}5Qbb{#%Qw6)lWc+5a+6%2eh$ccC`%`14#xexYAI?YN>JlfyJIH*sG)Br)Fvnzf+npVqa=n*H zR_fRaZtP!@uZqd&0x?G-8Ee!Q96`PxcH_7`FULM@*Bt~OxWv0eLGXrCU5(}{aY_-gIG`3~IL_ z{;OPXmLX#C%;)DvVME^Z;tGMr$0b$+kuz4=GOg_exM72gm31yq`gfe}-j!?- zFFYyF9fgN=U_KaM&gZ#rV;Tx{Gv0j6G#DvK_}?sV9#lpbzj&FJ{K-NZNI(XB(dfJS z#bb9PI8}Rsm6`8D$6=QUd_6PZ+hTD5@#*7F-wrlg3d6=}0jz-%SEB~_b-^&T-AUoV$D#t8_CHXq5%eNXQ z<3G~Yx>O2yC)&hW~iKEX__nx{2RB1d_A(Ub1Z0loP~u<6Sdx4*;=aNc4Vtf|MV z>c(cya0M8r>i0*wn_kqgco!FGPF(Zk>*zQqFsUJ z6Id*|AHkD#!V>n0=nGl&7>F)np>@rsT-`7gF?twTk=}b@X53MH^52ATUv`si@P28M zRYdosdoXfOzivs;d;2q46l3&lGVh^4vU#2ZtZV;S%F!A*3vh3tbZsZTSAjm(?Of5; zE44m&EIprZqen-9UKBNuo?h)y|9agGaVJeo)YZH3_Vq5nj;hlHi%=pAMkx`nbA;%+n>Nw2N- zugJTIAx~45Ve8F|KU6E9Fhy~9g3vv(QgPNzPbcc#?Ul}lvTUoXmJpXrh552u`Svkj zfG5+y*GvB@QbV!}zI^teKsF`uF;M}ba>;Sb4Nyeh_}D8cxU*1(K>VNQHgOxxtpldy zqhPS|<^jl@^)ZnBsP^ecr%yQ%>vf7&P{__)AI6etvoZH=;YE|x$-A4DudT@?KNaRw zo3AIO_GK!#srSA;KQGo^0US4+`-_Bmz)GAPe0AkN8-m4Q@a~6{JA#iQ%AOIAth8ZGwh`05r z0x4@AHn14r6QpK51-2gEF|L@?&~Zd=klvhSyd(N7gnN#ks_ltG(uu0_MCbFD7Zo?9 zkJF#a9ni-r1(Rm_U(|8Fh3t(SuRcv*e3~C1BD3ck{=CN7N!&BoJY~KEK5vI&uI1!U zZK5PoOLKD+*>gNHB|GT)M?N+x`8($eUv6vjwU78KvO1QF)k&X02kC-0BhzV(pbzX$ zrTLjgC=oVtPxN4xWI{a!q53|AU(m{5eIJD*~V2)LrT3vxP$_mom=7;c_Q+WwR_uv!W{5pdimuE<-c6#MXISw21) zobFX+@mB*4+ds=3LuIr_W8g@Wzvr*Ob4r{xsqyB4E6YT}0dTxL^V=q12+QP#3&=uM zEyTMU_%?OkO)-%TK|1l$ad`}Ik+D;3ANYZ+txqv z%9*K5$tZJ;#z!F*=5wBP`lXvovUO7q8|FFt_&H+N5}1#KbB=dcSYpTfA!+XeE_i@% zB3a-2V}m)}o8~;tcub-6VHUJYLfP?W)|rk$d|(QlddG7Cf9J)LNo=k6K|8TEg-tb63`<<+5UJj!9v# zH6ZfX_!tnV#Sf-l!7pnpeZXDx4>Pp+63{K{DU_&75<-jp+^ zt1k*KP>6Ddr_+fNu`}Y+esH0h`Ry8`=H#OXR4~m)n4G9TCB{DF$?it*Z4tjimV7)_ zSzhjSS{`?U2PL6aW+wj=xPSo!bXUjS$dLk~oK1l)!^UhW~k^`l8QdYwm6plEzNS>ogY7xy3OQ65plf_g7;Aidlb2C56dyZyyK#K1)u z?xOqwj$MDp*)aTHrkI8R5s?D~U;`o-o5nup)uIFilmqv!#>@~@hyd?x;fSA7F%8k< zSwJKc@M$d1R?;4ATP<%g^@wb{ADv0Wtvf)A2MKQH3}fLfW8$rIDbwO>q*a(TDPEC% zyB~tm*j6%sE#}33r61B6#;<%%HaMwZ9DR%uF}g&UQPW)BpDlQre!H;nkF$%B7+e#to#*!l$mU+6Zd~`3)t9 zwqs;V1jg$M9Z#6(I)y|ZyY*j+U}5M z=PaGzlQ49Q78d#ZJ9pY8q`ni3>q`IAx&fdn`}s7Wr7cw=ziT5%7Ylf}WCIorsy8r* zi)&1cI+l`N8rvz2cfKrM*BqL%%9oNN*Hs;pNW~T@9X|UhhB*Xl@w53s{ypW2# z4TDXps%O~{T(`@#NyGdQtGnk(d1QOeOu-?~9P(-FE+Xlytpej}EyW=TmV8sS_et z2Bu2PFhKRT_4-Z~TaaGPVcapb@Xb^MgqW(rOnb{k=aOxa$a^dQkL~24jA}769KK_Y zwxt1!uZ-qTF1f2GNtZPaA9hb*w2$2Ku4kGQQ*8WcDfMZ6cCU%$n(h?25gf76kKZTw zWeK+DN(*teE7B{`+nt`%I)hpU?sl!n677$p%=-H12o1^SIwq?W)FOar;33qAhEvV3Ezs1~py~m=OttgiV1Tx145Jnx zVI|TU6u?oZV7|!-f|8yH&Aq`yLFVPte+<;_5dIhdXh-v}{$bvGz*sqf4QntvUM_X1 z@pqXboaDx~;N4M~&p-2N2tol44aF&H`nwx$)O{3=X|+q#^xO9GjpFLW?Cm}ORja3- z8>U<`_IT+Lb>PH7;_8X`cB5$wDsV6bhtQGhyO@W)S%G^D8PtlBp88w{-yzlKEf_VZRzqx2b>iX0GYm*mvlCF zM|}V!L+(i3`V#|_VaaYz zj~fC$(U4~*szib=p;IsF5>+qV*gU1)Xy=i%PqtYf3t%r@DFhQ7 z=|)<49#ZwcGy`)J8jUU?tt#OZ=|cbwqw~8^!?=eU1unLsM7ATBD6WP%W#v!UqYluW zH?&Q0or~)lE*N-%Tp+6!&WUeE?09&|7yhCoBItH+Xr(zMF!zXy)~e>5#aqL4Y@$Z?Yd?>iSRJ(wj_Y9&N+aU=fpBJG(nIv7CfwP@8V;WO-Z zI%&ls1{+aq?5do`?M4^fl`LD0tyJhiN65nb5C&n*i^~376dQ?$ zm~VR_PCB4ZY~b2(T|erbFG?PFjnC(G*U+2W2NJGKh>LmbFgQmh__AeP(!`hc7n#0- z6oY^b;Dg^P)V}`>iVojvIC~2V1wt2BRQJtZxI;Z9<dtq=Vc8a{wo7C!ZTQ5zN0cOC z{kmK)uA*svw40d=y)WslZI-T|_lKgILE3KoGwM&hSXPf4;hvi%D9f4BipDesf$9m4A%rOb+>0Ydy?6X5P=ZNUA03i zjY;aQiY0QqGVEO%EG)_x)hp&nrnW{@z_L;D&B*n4{-oA8_obT%qf4Wp>2^UdbZ3;u z^=nL)TrH==P&Acfy^kgNmr=DTJ8 zCERM>$uSm)MR@$Xf$eyUkR*qHSJ7$I^^e{WRm^+};R5b7GA1jI*5R zc&vsZ9YMLBOlThH;sldBy4T~P|CC-k_xrWuQiekpx|M=jBOo0Y{3d*C1UHdzyG>g_ zG8k8qi2w|)kgy*d7OZ!*Q)hA{S3L?;{jq#6v#h!vA6ftvi2+t%ghC}!-I}1`DLnfb zM5aHRM0Q}UuKELB4GQOgfk3MR$#gKoskt6|pS*&-FKC#e9k-a_a9n-e%vio^VeGMG zplNy5PFl|VHzDom;*OZDfw-sEK1-H$*F)?5h_Xxm9xr1cPTr^}LtYJcV~}_Wwe<^Y zK1Fk|YCrSkd{Pj!7{*-XT%=$q{J%D$)q(&=PC_4jDiOxT`3rIW7>1V_dd0gkF~??x z=Z7xoh5FhAM`BWpVt@(43;7^2V!J7Yan#fRHOFOA5&H zgV6@7Q%FB8k5S|%?%-MGERSma-SSVBWMuNbO-b_#5@u>%LzU_FEDU@q^vx1y#0^Es ze;LCY2(9N}%JgNukc}1;f(R?JOv(zElCF!>f3erNtEzsdfJYnKT*Y&YBgGjWnpd7;cYzMAE) zMk|l-`H#oD=+gT3z?d!8N9$#LV5;yn?@sGq1z0Z-`)6CM!in%RE~NXjALyBftl|O_ZfzD`3*?F1TaqsaSdxxlar@4_o@2Va*UD-VC7k? zD;5u1eztU%p4|?wn8nP-rB|-n|vLbMmYc{k0CmU%LH*qow z22r5`GrefVp{p;3<4jOOK&Vn5naHNuqC1S2@6|i={e)TPRG7&jCmH;*`O5m67;WtXIaXyW;3)Io~Jj3VB@7jZy2}OLh>&p_I4Nk$wqsdtEtV|>F zO?#5pBpg7-hypF0RVvt4N!oXYb)q{WXD=l=s<`c*x%AgLKh?4@hR`iMbDD&`^1Dw3 z%7}g`j9?ujmcMCxCB8xnBnW?6{lrh3i8l&Z-*PL!z>;!vbv^kj{`=@uzs~Fll(1Nm zo7a(t*gWK_Y&9>E>YFp=-W791Wh3AlaskB|%6mcQJ7i=z_D@5Rw>X*&wjD9gah<=j z_O0R~!Orfv$#DeUH0-ONWAwhJ0LqvU7?*4NI z*ErC!gw+s$UCw&fv@xE@E_`Je%{xD0^2vjSrt2~gP)BOHo(m6};9+TLFG(I+zYb9U zGJ=1Pb{&LNJETu!nL2SjFFPA>g23S;*T``3N)Vq(z%M zQ1HHP9VU{AO7}Xlqk7Y**j|dSIMDlQG_5Of>4}%`3K8ut=^8vZP*l_wN?ifGaSvU0 zK7uIi;Sx*RIw9DTQHRZD5zsJWHhuoZ=?@K7CrobN`FyZ4kS5EzqgSRx;v-9Rx$5Du zKmDMk38x7hz@%@DLWqEa0Vl!Gerryy|4gAykkxbc%M(jIp{5`5?RiOd4-36t8y{Ny zcT%~8+Y~N{B@^fT+lRZ^Bjs2J1lHJvBAL z+9B}CZ1AQWK&Ls_Prnh#U&BVP?@ZE8|ZtOUrLkEh`N02pt_gKMo97F&-ZBO3MJJ zF=`Wa>}LeQ)mYbB;*9sUpt{S{OaI#-=v1c9Af3@oV5)iB+DU4&V7Km6Z|NU{njipt zqsI^7)L;w**19n7y2k1HxVEbuIs4*dcw5r!$9ES=(lCq?#hO{A!V<;Gl| z{jPhl07pQ$zolaxcC`oWZCw?Q@3Z?mr?z`F{pf1D!dIMamHG2egK`P{y5B!$F@JZN z9t5itpig3QJJGO*prDr#$2+3}y+Rm$0@tJ*ghbWv!WxYDCdw?SJe^~3KW)}GFAZDjf~QL%%%BkZqj&w0E*b2}QSxGHAVj z_BW2Oi0CG&@D=m)pn}x3a2b0{P_=|G( zxvtdiicwWnCp!)Lr5_Is;DTG5VqE@1L0N)q{gv=d+N9K9YxDgy!$3hhWBiyO{TqB5 zjWuVNaL3G1{cbkf6nZfTLuX`=qK?9y{bHU=Vh94^1_St2fhfT!l5Q@_D?j0HJGJQV zl&Z2G7{ik{3v}7;q%{cut0Np^K2r?x-k4W}?h7S~xjL1bSz2Y%JjQmr4Smq9VtL#q z&l;5v$^b0;;lBrNN!?U5aDkbI7%O6>lVNfK*63o`JEK6Zo3Y@OmudkaC|=0KyT*^n zt(bcw$K|#vm0k5=Y3zsNY+*qJ(&2%3(_eY6MWX@7Ag12>FYGZ`k`ND2d&0IZ<>VeNV9&B(nf|YJu!7hRc(^Y9g zY4C^Q{X2NkeMARU!1Hi|4`D7`z>y8DS}|7ZPqm&-n}2&0VU7oF?YMKyrET{>2H*k0 z_qGYE%}n2{@lX7nt_ahni}+T4O^I~-AYkaF@_ZV`#>9 z-axZfu2!om26il$(6d1!tU8~d&j@oTg0}VY7o2)L-s`rqXSed-8QAt(C}Bh;vP{)m zK+UHHTIOg%FHSrYgI}5d3)Q8+sP)PI-Sd{z(xK;sxjs|!+rx72&m2}H{S=!l zt?MX2xYG$r(y{nBkmt@CVxtRnovx!_{6M-XgEq3%95|_#JtY{)%NQ8JK5)6R`h{T- zADN)|nz+@zcUoT?(-ZRCFV_SNl8cX9l2w-t#932zxV!GR^UvB}Ae?A{QyzW-=&et_ zu+~Gn_+RXZc*atnvKt4nCJZW4r8&z;{afQ{1Ikw z8BJKVYdL*bzOd8?>akRe$Uw6R_nQWB?tBoP5XVn$jp}me zxu-Ua>f8;ixA&`=|`%EB!!!qU!*Ix5G)TK8Wo}y;s7bUn8)t z9D(M~O@~`D>lRlZkzl>EEA<8L9XM$C58CjxPR7wG6tkhYOkh0IEo}y3C-rmYku}Lr zOJ&be;aK1BQqU($@YWiCir*bMvm7YC!A;GeYefS2XSHP=O_4Irs<|JVKwdLxh1wp_#(Ahcc}Lss(T3zP>C5MkPu8 zZn(I?+tjt*C-s1jG?$Lwr0rkojB6i2uX`}_G=8|!UKT*0EM@#b7iIYmFd^_d)3*rV zflT#JG^4@^r%xrn(9RN>$%~zL0XfPaj}|ckhfYLql8`i%{QB$9s4mZpjh6Z+srTn02-B3qVT(=21Tn9U@c`Gu3dGM8!Vh- zIlQW@6DY65Lvb6<=00puV}1qxn|y!I!u(>08Rv1mTlf#+m>80+M|MP(whd!N@hs=@ zqXYqf{d>oBs{Cv00P=hiyE!svjPz6TR*HL=NAD07--;7$aDxKfhneq0m9RN%;OC)w?8Z?F+Va}=sw2lgvx360ml#aGLmso(2LMo&M zCtqLI7u`+Y&f%i@RE~AO5^~&`4xUIGaxWwv;Ulg1e=kc%SjSEHDO^5QrRHL;zK!4E zYi$A4y~N%+Rr?1;82a!QPar^|m<*d1tMfC8rm4P)k$cw3En;XeeB=!2!kBb|{POKC zu$k0}bDQH`ASwfnxB2n2dVa9YXreMWt*s1LOl$o;TFd6Xqpcc{8nw$4%9KBkd080e zRqgkO-J8kZ#NL2AT>6>d{T_dld?AtoJfyP^H*uQVlc6IRA>sEz&U#3{{piOVfI=Fd z_Nu_bDE?I1<-r`Um=XeJMOd{CNvA;V3ahY_xx3m(2EI^$2@;R!+7n_>E*uS#eGmwo z+#0n!V=w1H)TI2i2_nGU773|cK!NR`G4uC|16qx}RY^yLir7!L;0cx%!TqRj85o#q zdZ|hAyq^S)B&KC`Xcs)$f}GJA1A{be4;-yO6~&bF>+h!5{E~aP_q6DM zp%x3|s|%c;U5**Ae-pmf+ob%EPc0jOusRqpZW9s96!jDFyL<6U8R=bayw@i73Euke z<%^6b1%r=<16bo8!J*zG9>O(ANmBz^AT5#4-&5%w=g#=8Qj6mF* zY4WsuauLWp*+oa1b6{|Mt|%P!jwt@6Ey-~FwFGA@_RU<(+PXCyGi(7tY6Kj_b-orbe5cPKrcY7! zln~JdIKvURJ7h!cAnS*Sr*o(W$M<{06kT*O%xjm!DBmJJ`oc>AmIzH#6Kc#Jy zd8J2|PbZuj-gU`BseVVg3z}HK`&6v9{}4}w3tY;MQkHWPr(~@TkH>)p1tg)G11lfO z*UByC@;{7bFu%S?I_HLW`INWqG)HI?xGC>e?%!>(Z23K$%Z3!QPs_(1S?V?c_9F@p z+`QYcGf4zJo#uu=TISqWoOgEZvz zkSO`SjgHufPDK0MipVP;U6s^n^0e^tk9Fv+Aluug;POX~jY_@tZ18Yas;?(hNIcqD z*UsBct7Od#UWI$_OJ{c1n~iA7^{t>qCiu0jQd+L7G&XQC@2*y$?KAbSRu@vHDYyZi z?mLaXR_3LO8ooRbxuemC;j4u)2*^|pBq4?>9-70@{x1Uw`rp-OvW&i$EOFtgT?H+72hHcPwpeX!vTswuO=1T0&Y(6aqc34F!QW&!Ij7lwT`HOTYkDdM2LizCA( zphM1}ACO)3^T@|^Hc2YE8EsF6dSBDI-uVAc?Tb>Ug1?(XY;@v>TNZ?M-nws$M zMo185rsXV~b6IUwKW!pII*f%RXqRkN>_ftI8{qnvFvO#mKZTr>+NQoa2h8Te?^5<4 za1WYgSExeK&T0=5d3R=4C|HGV2rPS`ZM7}wR5j>6wRb7>R^>oSp5&$kuU;JueN+w{ zJd#|l6e>lUA2$W3}w|I{WWcNQ-J^V@+6Fa7?(LOA6rQK~74) zws{EkTxsh#Q7MhgI)Se+3kHr2daz>0IJUGuvSTLunzecw<{1KfStbV+z8?5b9?-*7 zPqd;y!lu8HWc^Z>fqz70tF`vg!L`y3f#e?c#Rfl!mw#fDX}qk ztS)+RAc~U_6(6N8_>Tb(AugYMUNS|j9{{`nB`Q4A3M4mQ zE?_f)fKgGaqxAYuXIZbd={rJX$N+E9QI|sDz5CToimVoww)?GWnTfoXNV6t8;3@k# zkQ!I!$NCmmpY3Rk8ZwS9*R%4Oo%2&_hu@J~2fJ8=AcP2?4uvttk5{p30cI*v8-R?= zz%^5|Ep5dn%`zZ@@gc4jMk7L#TVNpm{2P|0B67!Z)IE7K_tfpk%S^7yVex~W?+9Tz zZgM#VGBP@DZAz_^T42NIM7@+az<$`>zxp5zx{JrS4!ise%66M%FcIR-y!>X&EofJ8 zMKZq!pPNqNO>ftSl?q9RBzkWAsZ>V$a13Y`L+s`pNoEeIhBpD3cngV5F%0VLgzP5j6ls{$h3tdv{&63@tpjIjt1D zZ%hqB6O4(chY$It1TX{>AV3soS+``#PvIkQaCJMhv*B%T<3E+no;ye54R1+e;KTt#k}a6i6%(uCU2pWc$AueVwFEv&S# z?Q4t~#bjR8%!}X4->)$D~aFY%UPTlu^9@Z_=r9+1lj{YPbvBC3wVc7FQ@8Ut0+Fiauwp>c3(cXd3`p9DIPIO@q`iD==uyitvgq`!6! zBgcWTkFcbDXm*-*al3RJWzY~f)i`m|oPXr9&!CH%v`c>s`kX4F{x1>M(1W zJqPJ}_#(4}HkcuTP>b2i>cv5$D=9s>9Fv!v6IqOqnQI`mxKOSB@qA$Dnvfo=2m*i; z|4eY=;XI^azcWwf`Kk1{xsV&O4?_$d@zM&dlCuzq>6N0;I5}kS_F@Rj^gS|)R(9X5 zwG@A^I{AdRLTxEYDJ^oGLkZa9qL)wzIg9bF6Ze*~HftE}Q9Bm=ClzEcEV zu--0#!U6DI8brVKsq4G8N_`_?!Ln9nx;{*TAgxZD5d?v(cEpNkQGp0wBd>_Q#bnqW z9x_j8XH;0MF14-?Y`QnFlurpSDdi4tw!QJ6RyLEJn|W+-T;6+qJNs7{d_?5g=gvR;LB!TBt+0@@CO) zCmEys{uM^G&dZiuvmO*#o71S7asFW`We&Se*F)o(p9ht0BX}j?-GhAS=r-L7!TnrM zpih=gG$D(vo9N%d+_~qF&n=@SL{vKKwlepU=I&b2`+q}yK|W1KM@0DT(-D#Hq(px` zb59#rCzR%yJamvB$FXP@0mF^;DpCx;1cMDSpJKzZ^3{VN8Ewlj_c{2~_+IMYapq37I4t zJW4AZ`V;&f;(&N_8YL9%lcU#cs(?9-R}f1vvS2pg_(*pT#XnYZ`3*p^lHF?T1EWuogJc)$4{6{=OW!; zNH+xKAwr)s^`505`4p(Xpo#OrN|5bM@Z~}|P7wqbhmmnL*sQC^|axHKjF z79S7IZ}wmjsq=DR*g&V4em+HnHG9cogX~gOJUh<#3&V=QSqbflJ)bf)6{qlS83m9_ zA%Q#4sdq2-TE9z%xf*lCR>pR<2u{I2yK;$cF`+wQ)9JWnVOGBN-f97&j4vQWz<;At zp$TkGDj;2iV;}$t{zm$3O3CjV31R3j1Lju3qu7%A5V~R#tiFLKxdD5&lf^fM`nIS` zaIwf$+N)&UFUxHycm{`;2!mj=>d->Le#6l9vw5)^k21MGx6ZR4!u}E}jpJXG+3LK0ufQl& z&-w1s4=7$*pA}EL#ixK~;0(o6rE;#QkHT1pkt1lbu*J&EtO#gRdy8-0?-YTyKz((ELfK+l@sX4a zHMQ8`o+9y-I!$S1m3FsC0xU;U@y`?Ra9F2GOj_?h6|3~%3^mNU6S>A}uLjuIxRb&) zllG9L9GfbW`Kn5W|#B+SyFWT>o57!Vod&p#ukQ-r1VmYxaYg`^UpOJt*o_zv!sVm$t{yqn_|1enrT*w zeFq2WDMcL&h!<(3fr2*81coj97JKH5T8hdavE3Ytb4e!e#?Gt*$)tc zQDDZP#7cD#agI{#`b2Rx9K~S+U!#sc>GY7X?slhlP{aHd&_=>PweEGzJSal%CrJ*= z5F^$wWY;y?;6aE;qsS<&zu=N%;}GBif|tG5kV~gy=@M?`{PW(L-@-w)(AjOJL9X~l zs@*4oviYj4T3y4P689v|(G*I)nHwh{h`<8+p`=0apOh}_bt^o^1ZZ+o=SMeiE$PMCqD%{ zI88(vvX}LOl!(e02m#q&?o3{v&}N&BKywwNUE<$059xHNNNxpo9lE(4rdXNCMT3Ol zB_Fa`o&m*kSI&-Oc0Jrr6F-)Yzo>bbgOMIt!3_>omlEb2giNzb=uTIf>)4 z&pkcANy2zIW@5Z@f#8TRHecI{8!9lmUKRC}^L;)BwsY<^9s^B2M2?_D)38xq^jWoZ z$Yggh-}ZP@cx7?4PQ%W4)nYY! zT~z=WWWXvy4PpPk-u9;s{tf-5a_Kx`NO&J0ALLU}rfVIUvuY~_p$c`cpa|WQDce$p z88wZ9Y<#LiS56V)tygQTKbkZ?`qy$qalpu93ATnE+# zAHXxT9r)^v)U`QvyM-s-`HVhw6tp88RW*$&L{@&v>@SDT^^dp0h;#i=Q+tF)WGNwW zr1$5#%R9ba`LSxuvNFhn6h4KdV${&>Z*6dESA{d}O9zRY?_&kQJQeAdc+XDdp(Y#? ze#B#c=Sd=aY|ttg{?XnVx88Y7*A?f4H#wmd+kZ5QU93(59`l_i%?b(ZasIDd&o`8B zYJ;Pn1ts7crMPMtNFH0w6(pm(?FdVx_j9CWDo-}h)st{Ivo zbltjPt3NP#zv~@asbs+OaG~H_8G-Ao7iJHiCB#~7m!Zag#L^$vN^wrN=hjuMQz4

    W=LG+)BI#hpNiU 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 FtzbkEhhzW% literal 234832 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 z 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

    jVFdz&MolTrEOV<&v~pK6Eg!G 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

    H|1=;3KY|MfY#17W5Fe}*r^yH2-$lE4H&Vn@# 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⪋)> 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 z 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 literal 230127 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 y0tg_000IagfB*srAbHx6-hy(yfq~w(V diff --git a/index.html b/index.html index 3cabd9b..cffcff4 100644 --- a/index.html +++ b/index.html @@ -14,8 +14,8 @@ - - + + diff --git a/search/index.html b/search/index.html index 1385633..d7d3b18 100644 --- a/search/index.html +++ b/search/index.html @@ -14,8 +14,8 @@ - - + + diff --git a/talks/index.html b/talks/index.html index b54708a..721ca51 100644 --- a/talks/index.html +++ b/talks/index.html @@ -14,8 +14,8 @@ - - + +

    Talks

    Featured talks I presented on various events.

    Shift Left Testing with Packit and Testing Farm

    In today's fast-paced software development landscape, ensuring the quality and reliability of upstream contributions is crucial. The traditional approach of testing at the end of the development cycle is no longer sufficient. To address this challenge, we present "Shift Left Your Testing with Packit and Testing Farm", a talk that introduces two powerful tools designed to simplify and enhance the testing process for the upstream contributions.

    Packit and Testing Farm provide a dead simple way to build and test your upstream contributions against both public or internal Red Hat testing infrastructure. In this talk, we will explore the capabilities of both tools and demonstrate how they can be seamlessly integrated into your development workflow.

    In addition to the current capabilities, we will share our plans for Packit and Testing.

    • QEcamp23
    • virtual
    • 11/2023

    Packit: RPM integration, all in one

    Do you want to automate how you build and test your RPM packages? Do you maintain any package in Fedora and want to automate the releases? Or are you just interested in CI/CD on GitHub or GitLab, Fedora and integration of upstream projects with RPM-based Linux distributions? In this session, we are going to deep-dive into features of Packit that can help you do your day-to-day job.
    • DevConf.cz
    • Brno, Czechia
    • 6/2023

    Also presented on:

    • DevConf.cz Mini in Brno, Czechia (3/2023)

    Credits to Paweł Kosiec for implementing his own React components for talks.

    mf

    blog and additional materials for courses at φ

    About Me

    I'm working in Red Hat in the Packit team and studying at FI MUNI while also tutoring some courses there.

    Content

    On this page you can find my blog or unofficial materials I have written over the course of teaching multiple courses at the FI.

    Mastodon

    Feel free to contact me on any of the following Mastodon accounts: Fosstodon or Hachyderm.io