Add notes on sorting algorithms and equiv-trans.
parent
9cabe16101
commit
00f23d5f94
|
@ -72,11 +72,14 @@
|
||||||
"**/*.excalidraw.md"
|
"**/*.excalidraw.md"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Added Media": [],
|
"Added Media": [
|
||||||
|
"insertion-sort.gif",
|
||||||
|
"selection-sort.gif"
|
||||||
|
],
|
||||||
"File Hashes": {
|
"File Hashes": {
|
||||||
"algorithms/index.md": "1583c07edea4736db27c38fe2b6c4c31",
|
"algorithms/index.md": "1583c07edea4736db27c38fe2b6c4c31",
|
||||||
"algorithms/sorting/index.md": "7b3b43d63ab2143e1314bb1b4e8392d2",
|
"algorithms/sorting/index.md": "6fada1f3d5d3af64687719eb465a5b97",
|
||||||
"algorithms/sorting/insertion-sort.md": "6ad645860c9c281eb8eb06c93135746f",
|
"algorithms/sorting/insertion-sort.md": "a531d611f4e2908fc4153b1b92077661",
|
||||||
"bash/index.md": "3b5296277f095acdf16655adcdf524af",
|
"bash/index.md": "3b5296277f095acdf16655adcdf524af",
|
||||||
"bash/prompts.md": "61cb877e68da040a15b85af76b1f68ba",
|
"bash/prompts.md": "61cb877e68da040a15b85af76b1f68ba",
|
||||||
"bash/quoting.md": "b1d8869a91001f8b22f0cdc54d806f61",
|
"bash/quoting.md": "b1d8869a91001f8b22f0cdc54d806f61",
|
||||||
|
@ -99,7 +102,7 @@
|
||||||
"posix/index.md": "f7b1ae55f8f5e8f50f89738b1aca9111",
|
"posix/index.md": "f7b1ae55f8f5e8f50f89738b1aca9111",
|
||||||
"posix/signals.md": "2120ddd933fc0d57abb93c33f639afd8",
|
"posix/signals.md": "2120ddd933fc0d57abb93c33f639afd8",
|
||||||
"templates/daily.md": "7866014e730e85683155207a02e367d8",
|
"templates/daily.md": "7866014e730e85683155207a02e367d8",
|
||||||
"posix/regexp.md": "2529451da41c81b891ea8ce82cca549e",
|
"posix/regexp.md": "e41bf86b770958316df1e20578d6020f",
|
||||||
"journal/2024-02-04.md": "e2b5678fc53d7284b71ed6820c02b954",
|
"journal/2024-02-04.md": "e2b5678fc53d7284b71ed6820c02b954",
|
||||||
"gawk/regexp.md": "dbd5f9f85a2658b304a635a47379e871",
|
"gawk/regexp.md": "dbd5f9f85a2658b304a635a47379e871",
|
||||||
"_templates/daily.md": "7866014e730e85683155207a02e367d8",
|
"_templates/daily.md": "7866014e730e85683155207a02e367d8",
|
||||||
|
@ -110,8 +113,15 @@
|
||||||
"_journal/2024-02-02.md": "a3b222daee8a50bce4cbac699efc7180",
|
"_journal/2024-02-02.md": "a3b222daee8a50bce4cbac699efc7180",
|
||||||
"_journal/2024-02-01.md": "3aa232387d2dc662384976fd116888eb",
|
"_journal/2024-02-01.md": "3aa232387d2dc662384976fd116888eb",
|
||||||
"_journal/2024-01-31.md": "7c7fbfccabc316f9e676826bf8dfe970",
|
"_journal/2024-01-31.md": "7c7fbfccabc316f9e676826bf8dfe970",
|
||||||
"logic/equiv-trans.md": "82a3376977bc5579fba5f9201c9f2c14",
|
"logic/equiv-trans.md": "660a2a08ddcf47c05af3f8704feb5931",
|
||||||
"_journal/2024-02-07.md": "9197386e8caaf9502f12fdc10d68fa9f"
|
"_journal/2024-02-07.md": "8d81cd56a3b33883a7706d32e77b5889",
|
||||||
|
"algorithms/loop-invariants.md": "cbefc346842c21a6cce5c5edce451eb2",
|
||||||
|
"algorithms/loop-invariant.md": "d883dfc997ee28a7a1e24b995377792b",
|
||||||
|
"algorithms/running-time.md": "5efc0791097d2c996f931c9046c95f65",
|
||||||
|
"algorithms/order-growth.md": "bf43ad8c16037baf1e865839f5e46704",
|
||||||
|
"_journal/2024-02-08.md": "26ba491937c92e55d3a43f8800677dcb",
|
||||||
|
"algorithms/sorting/selection-sort.md": "f31cf7e706504b9be48bed7af6e37074",
|
||||||
|
"algorithms/index 1.md": "6fada1f3d5d3af64687719eb465a5b97"
|
||||||
},
|
},
|
||||||
"fields_dict": {
|
"fields_dict": {
|
||||||
"Basic": [
|
"Basic": [
|
||||||
|
|
|
@ -4,10 +4,13 @@ title: "2024-02-07"
|
||||||
|
|
||||||
- [x] Anki Flashcards
|
- [x] Anki Flashcards
|
||||||
- [x] KoL
|
- [x] KoL
|
||||||
- [ ] Sheet Music (10 min.)
|
- [x] Sheet Music (10 min.)
|
||||||
- [ ] OGS (1 Life & Death Problem)
|
- [ ] OGS (1 Life & Death Problem)
|
||||||
- [ ] Korean (Read 1 Story)
|
- [x] Korean (Read 1 Story)
|
||||||
- [ ] Interview Prep (1 Practice Problem)
|
- [x] Interview Prep (1 Practice Problem)
|
||||||
- [ ] Log Work Hours (Max 3 hours)
|
- [x] Log Work Hours (Max 3 hours)
|
||||||
|
|
||||||
* Read section 4.1 of "GAWK: Effective AWK Programming".
|
* Read section 4.1 of "GAWK: Effective AWK Programming".
|
||||||
|
* Began translating more of "The Science of Programming" into flashcards.
|
||||||
|
* Begin re-reading order of growth concepts.
|
||||||
|
* Solved [Palindrome Number](https://leetcode.com/problems/palindrome-number/) and [Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/description/) (though my solution in the latter is subpar, using recursion instead of dynamic programming).
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
title: "2024-02-08"
|
||||||
|
---
|
||||||
|
|
||||||
|
- [x] Anki Flashcards
|
||||||
|
- [x] KoL
|
||||||
|
- [ ] Sheet Music (10 min.)
|
||||||
|
- [ ] OGS (1 Life & Death Problem)
|
||||||
|
- [ ] Korean (Read 1 Story)
|
||||||
|
- [ ] Interview Prep (1 Practice Problem)
|
||||||
|
- [ ] Log Work Hours (Max 3 hours)
|
||||||
|
|
||||||
|
* Add notes on selection sort.
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: Sorting
|
title: Sorting
|
||||||
TARGET DECK: Obsidian::STEM
|
TARGET DECK: Obsidian::STEM
|
||||||
FILE TAGS: algorithm sorting
|
FILE TAGS: algorithm::sorting
|
||||||
tags:
|
tags:
|
||||||
- algorithm
|
- algorithm
|
||||||
- sorting
|
- sorting
|
|
@ -0,0 +1,90 @@
|
||||||
|
---
|
||||||
|
title: Loop Invariant
|
||||||
|
TARGET DECK: Obsidian::STEM
|
||||||
|
FILE TAGS: algorithm
|
||||||
|
tags:
|
||||||
|
- algorithm
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A loop invariant $P$ is a condition that holds before, during, and after each iteration of a loop (e.g. `for` or `while`). These "timings" correspond to the three necessary properties of an invariant:
|
||||||
|
|
||||||
|
* Initialization
|
||||||
|
* $P$ is true before the first iteration of the loop.
|
||||||
|
* Maintenance
|
||||||
|
* If $P$ is true before an iteration, $P$ is also true before the next iteration.
|
||||||
|
* Termination
|
||||||
|
* $P$ provides a condition used to prove an algorithm's correctness.
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What are the three necessary properties of a loop invariant?
|
||||||
|
Back: Initialization, maintenance, and termination.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707329732922-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What does it mean for loop invariant $P$ to respect initialization?
|
||||||
|
Back: $P$ is true before the first iteration of the loop.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707329732926-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What does it mean for loop invariant $P$ to respect maintenance?
|
||||||
|
Back: If $P$ is true before an iteration, $P$ is also true before the next iteration.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707329732928-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What does it mean for loop invariant $P$ to respect termination?
|
||||||
|
Back: $P$ provides a condition used to prove an algorithm's correctness.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707329732929-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
At what point in the following should initialization of a loop invariant be checked?
|
||||||
|
```c
|
||||||
|
for (int i = 0; i < n; ++i) { ... }
|
||||||
|
```
|
||||||
|
Back: After `int i = 0` but before `i < n`.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
Tags: c
|
||||||
|
<!--ID: 1707329732931-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
Notice loop invariants mirror mathematical induction. Initialization is analogous to an inductive base case while iteration is analogous to the inductive step.
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Cloze
|
||||||
|
Loop invariants are to {initialization} whereas mathematical induction is to {a base case}.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707329951146-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Cloze
|
||||||
|
Loop invariants are to {maintenance} whereas mathematical induction is to {the inductive step}.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707329951148-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Which loop invariant property has no analogy to mathematical induction?
|
||||||
|
Back: Termination
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707329951150-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
|
@ -0,0 +1,96 @@
|
||||||
|
---
|
||||||
|
title: Order of Growth
|
||||||
|
TARGET DECK: Obsidian::STEM
|
||||||
|
FILE TAGS: algorithm::complexity
|
||||||
|
tags:
|
||||||
|
- algorithm
|
||||||
|
- complexity
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The **running time** of an algorithm is usually considered as a function of its **input size**. How input size is measured depends on the problem at hand. For instance, [[index 1|sorting]] algorithms have an input size corresponding to the number of elements to sort.
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How is the running time of a program traditionally measured?
|
||||||
|
Back: As a function of its input size.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707334419352-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How do you determine the input size used to measure an algorithm's running time?
|
||||||
|
Back: This depends entirely on the specific problem/algorithm.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707334419356-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What *concrete* measure is typically used to measure running time?
|
||||||
|
Back: The number of primitive operations executed.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707334419359-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What *abstract* measure is typically used to measure running time?
|
||||||
|
Back: It's order of growth.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707344177499-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Why does Cormen et al. state the scope of average-case analysis is limited?
|
||||||
|
Back: What constitutes an "average" input isn't always clear.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707334419363-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What about running time are algorithm designers mostly interested in?
|
||||||
|
Back: It's order of growth.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707344177503-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How does order of growth relate to running time?
|
||||||
|
Back: Order of growth measures how quickly running time grows with respect to input size.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707344177506-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Why are lower-ordered terms ignored when determining order of growth?
|
||||||
|
Back: They become less significant as input size grows.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707344177510-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Why are leading coefficients ignored when determining order of growth?
|
||||||
|
Back: They become less significant as input size grows.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707344177513-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Polynomials describing order of growth usually have what two parts ignored?
|
||||||
|
Back: Coefficients and lower-ordered terms.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707344177515-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
* Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: Insertion Sort
|
title: Insertion Sort
|
||||||
TARGET DECK: Obsidian::STEM
|
TARGET DECK: Obsidian::STEM
|
||||||
FILE TAGS: algorithm sorting
|
FILE TAGS: algorithm::sorting
|
||||||
tags:
|
tags:
|
||||||
- algorithm
|
- algorithm
|
||||||
- sorting
|
- sorting
|
||||||
|
@ -9,16 +9,16 @@ tags:
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
| Property | Value |
|
Property | Value
|
||||||
| ---------- | -------- |
|
---------- | --------
|
||||||
| Best Case | $O(n)$ |
|
Best Case | $O(n)$
|
||||||
| Worst Case | $O(n^2)$ |
|
Worst Case | $O(n^2)$
|
||||||
| Avg. Case | $O(n^2)$ |
|
Avg. Case | $O(n^2)$
|
||||||
| Memory | $O(1)$ |
|
Memory | $O(1)$
|
||||||
| In place | Yes |
|
In place | Yes
|
||||||
| Stable | Yes |
|
Stable | Yes
|
||||||
|
|
||||||
Insertion sort works by advancing an index `i` through an array `A[1..n]` such that `A[1..i]` is kept in sorted order.
|
![[insertion-sort.gif]]
|
||||||
|
|
||||||
%%ANKI
|
%%ANKI
|
||||||
Basic
|
Basic
|
||||||
|
@ -52,6 +52,14 @@ Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambri
|
||||||
<!--ID: 1706926586951-->
|
<!--ID: 1706926586951-->
|
||||||
END%%
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is insertion sort's average case runtime?
|
||||||
|
Back: $O(n^2)$
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707329732933-->
|
||||||
|
END%%
|
||||||
|
|
||||||
%%ANKI
|
%%ANKI
|
||||||
Basic
|
Basic
|
||||||
Is insertion sort in place?
|
Is insertion sort in place?
|
||||||
|
@ -83,10 +91,49 @@ void insertion_sort(const int n, int A[static n]) {
|
||||||
|
|
||||||
%%ANKI
|
%%ANKI
|
||||||
Basic
|
Basic
|
||||||
What loop invariant is maintained in insertion sort?
|
What sorting algorithm does the following demonstrate?
|
||||||
Back: `A[1..i]` is in sorted order.
|
![[insertion-sort.gif]]
|
||||||
|
Back: Insertion sort.
|
||||||
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
<!--ID: 1706927594718-->
|
<!--ID: 1707400559085-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
## Loop Invariant
|
||||||
|
|
||||||
|
Consider [[loop-invariant|loop invariant]] $P$ given by
|
||||||
|
|
||||||
|
> `A[0..i-1]` consists of the original `A[0..i-1]` elements but in sorted order.
|
||||||
|
|
||||||
|
We prove $P$ maintains the requisite properties:
|
||||||
|
|
||||||
|
* Initialization
|
||||||
|
* When `i = 1`, `A[0..0]` contains a single element. This trivially satisfies $P$.
|
||||||
|
* Maintenance
|
||||||
|
* Suppose $P$ holds for some `1 ≤ i < n`. Then `A[0..i-1]` consists of the original `A[0..i-1]` elements but in sorted order. On iteration `i + 1`, the nested for loop puts `A[0..i]` in sorted order. At the end of the iteration, `i` is incremented meaning `A[0..i-1]` still satisfies $P$.
|
||||||
|
* Termination
|
||||||
|
* The loop ends because `i < n` is no longer true. Then `i = n`. Since $P$ holds, this means `A[0..n-1]`, the entire array, is in sorted order.
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Given array `A[0..n-1]`, what is insertion sort's loop invariant?
|
||||||
|
Back: `A[0..i-1]` consists of the original `A[0..i-1]` elements but in sorted order.
|
||||||
|
<!--ID: 1707332638371-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is initialization of insertion sort's loop invariant?
|
||||||
|
Back: Sorting starts with an singleton array which is trivially sorted.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707332638373-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is maintenance of insertion sort's loop invariant?
|
||||||
|
Back: Each iteration puts the current element into sorted order.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707332638375-->
|
||||||
END%%
|
END%%
|
||||||
|
|
||||||
## Analogy
|
## Analogy
|
||||||
|
@ -111,6 +158,39 @@ Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambri
|
||||||
<!--ID: 1706927594732-->
|
<!--ID: 1706927594732-->
|
||||||
END%%
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How does insertion sort partition its input array?
|
||||||
|
Back:
|
||||||
|
```
|
||||||
|
[ sorted | unsorted ]
|
||||||
|
```
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707399790957-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How many comparisons does insertion sort typically perform with `x`?
|
||||||
|
```
|
||||||
|
[ sorted | x : unsorted ]
|
||||||
|
```
|
||||||
|
Back: One plus however many elements in `sorted` are greater than `x`.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707399790958-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Which element will insertion sort move to `sorted`?
|
||||||
|
```
|
||||||
|
[ sorted | unsorted ]
|
||||||
|
```
|
||||||
|
Back: The first element of `unsorted`.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707399790960-->
|
||||||
|
END%%
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
* Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
* Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.9 KiB |
|
@ -0,0 +1,155 @@
|
||||||
|
---
|
||||||
|
title: Selection Sort
|
||||||
|
TARGET DECK: Obsidian::STEM
|
||||||
|
FILE TAGS: algorithm::sorting
|
||||||
|
tags:
|
||||||
|
- algorithm
|
||||||
|
- sorting
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Property | Value
|
||||||
|
---------- | --------
|
||||||
|
Best Case | $O(n^2)$
|
||||||
|
Worst Case | $O(n^2)$
|
||||||
|
Avg. Case | $O(n^2)$
|
||||||
|
Memory | $O(1)$
|
||||||
|
In Place | Yes
|
||||||
|
Stable | Yes
|
||||||
|
|
||||||
|
![[selection-sort.gif]]
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is selection sort's best case runtime?
|
||||||
|
Back: $O(n^2)$
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707398773323-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is selection sort's worst case runtime?
|
||||||
|
Back: $O(n^2)$
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707398773326-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is selection sort's average case runtime?
|
||||||
|
Back: $O(n^2)$
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707398773327-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Is selection sort in place?
|
||||||
|
Back: Yes
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707398773328-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Is selection sort stable?
|
||||||
|
Back: Yes
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707398773330-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
```c
|
||||||
|
void swap(int i, int j, int *A) {
|
||||||
|
int tmp = A[i];
|
||||||
|
A[i] = A[j];
|
||||||
|
A[j] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void selection_sort(const int n, int A[static n]) {
|
||||||
|
for (int i = 0; i < n - 1; ++i) {
|
||||||
|
int mini = i;
|
||||||
|
for (int j = i + 1; j < n; ++j) {
|
||||||
|
if (A[j] < A[mini]) {
|
||||||
|
mini = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swap(i, mini, A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What sorting algorithm does the following demonstrate?
|
||||||
|
![[selection-sort.gif]]
|
||||||
|
Back: Selection sort.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707400943836-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
## Loop Invariant
|
||||||
|
|
||||||
|
Consider [[loop-invariant|loop invariant]] $P$ given by
|
||||||
|
|
||||||
|
> On each iteration, `A[0..i-1]` is a sorted array of the `i` least elements of `A`.
|
||||||
|
|
||||||
|
We prove $P$ maintains the requisite properties:
|
||||||
|
|
||||||
|
* Initialization
|
||||||
|
* When `i = 0`, `A[0..-1]` is an empty array. This trivially satisfies $P$.
|
||||||
|
* Maintenance
|
||||||
|
* Suppose $P$ holds for some `0 ≤ i < n - 1`. Then `A[0..i-1]` is a sorted array of the `i` least elements of `A`. Our inner loop then finds the smallest element in `A[i..n]` and swaps it with `A[i]`. Therefore `A[0..i]` is not a sorted array of the `i + 1` least elements of `A`. At the end of the iteration, `i` is incremented meaning `A[0..i-1]` still satisfies $P$.
|
||||||
|
* Termination
|
||||||
|
* On termination, `i = n - 1` and `A[0..n-2]` are the `n - 1` least elements of `A` in sorted order. But, by exhaustion, `A[n-1]` must be the largest element meaning `A[0..n-1]`, the entire array, is in sorted order.
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Given array `A[0..n-1]`, what is selection sort's loop invariant?
|
||||||
|
Back: `A[0..i-1]` is a sorted array of the `i` least elements of `A`.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707398773331-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is initialization of selection sort's loop invariant?
|
||||||
|
Back: Sorting starts with an empty array which is trivially sorted.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707398773333-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is maintenance of selection sort's loop invariant?
|
||||||
|
Back: Each iteration puts the next least element into the sorted subarray.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707398773334-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How does selection sort partition its input array?
|
||||||
|
Back:
|
||||||
|
```
|
||||||
|
[ sorted | unsorted ]
|
||||||
|
```
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707399790952-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Which element will selection sort move to `sorted`?
|
||||||
|
```
|
||||||
|
[ sorted | unsorted ]
|
||||||
|
```
|
||||||
|
Back: The least element in `unsorted`.
|
||||||
|
Reference: Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
||||||
|
<!--ID: 1707399790955-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* Thomas H. Cormen et al., *Introduction to Algorithms*, 3rd ed (Cambridge, Mass: MIT Press, 2009).
|
|
@ -499,6 +499,14 @@ Reference: Gries, David. *The Science of Programming*. Texts and Monographs in
|
||||||
<!--ID: 1706994861360-->
|
<!--ID: 1706994861360-->
|
||||||
END%%
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What distinguishes an equality from an equivalence?
|
||||||
|
Back: An equivalence is an equality that is also a tautology.
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707316178709-->
|
||||||
|
END%%
|
||||||
|
|
||||||
## Equivalence Rules
|
## Equivalence Rules
|
||||||
|
|
||||||
* Rule of Substitution
|
* Rule of Substitution
|
||||||
|
@ -563,6 +571,44 @@ Reference: Gries, David. *The Science of Programming*. Texts and Monographs in
|
||||||
<!--ID: 1707253246458-->
|
<!--ID: 1707253246458-->
|
||||||
END%%
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is a "theorem" in the equivalence-transformation formal system?
|
||||||
|
Back: An equality derived from the axioms and inference rules.
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707316178712-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How is e.g. the Law of Implication proven in the system of evaluation?
|
||||||
|
Back: With truth tables
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707316178714-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How is e.g. the Law of Implication proven in the formal system?
|
||||||
|
Back: It isn't. It is an axiom.
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707316178715-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Cloze
|
||||||
|
The system of evaluation and formal system are connected by the following biconditional: {$e$ is a tautology} iff {$e = T$ is a theorem}.
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707316178717-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Cloze
|
||||||
|
The {1:system of evaluation} is to {2:"$e$ is a tautology"} whereas the {2:formal system} is to {1:"$e = T$ is a theorem"}.
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707316276203-->
|
||||||
|
END%%
|
||||||
|
|
||||||
## Normal Forms
|
## Normal Forms
|
||||||
|
|
||||||
Every proposition can be written in **disjunctive normal form** (DNF) and **conjunctive normal form** (CNF). This is evident with the use of truth tables. To write a proposition in DNF, write its corresponding truth table and $\lor$ each row that evaluates to $T$. To write the same proposition in CNF, apply $\lor$ to each row that evaluates to $F$ and negate it.
|
Every proposition can be written in **disjunctive normal form** (DNF) and **conjunctive normal form** (CNF). This is evident with the use of truth tables. To write a proposition in DNF, write its corresponding truth table and $\lor$ each row that evaluates to $T$. To write the same proposition in CNF, apply $\lor$ to each row that evaluates to $F$ and negate it.
|
||||||
|
@ -644,6 +690,138 @@ Reference: Gries, David. *The Science of Programming*. Texts and Monographs in
|
||||||
<!--ID: 1707311869003-->
|
<!--ID: 1707311869003-->
|
||||||
END%%
|
END%%
|
||||||
|
|
||||||
|
## Short-Circuit Evaluation
|
||||||
|
|
||||||
|
The $\textbf{cand}$ and $\textbf{cor}$ operator allows short-circuiting evaluation in the case of undefined ($U$) values.
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What truth values do short-circuit evaluation operators act on?
|
||||||
|
Back: $T$, $F$, and $U$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708622-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What C operator corresponds to $\textbf{cand}$?
|
||||||
|
Back: `&&`
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
Tags: c
|
||||||
|
<!--ID: 1707316606004-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Why is $\textbf{cand}$ named the way it is?
|
||||||
|
Back: It is short for **c**onditional **and**.
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708625-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How is $p \textbf{ cand } q$ written as a conditional?
|
||||||
|
Back: $\textbf{if } p \textbf{ then } q \textbf{ else } F$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708627-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
When can $\textbf{cand}$ evaluate to a non-$U$ value despite being given a $U$ operand?
|
||||||
|
Back: $F \textbf{ cand } U = F$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708628-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What C operator corresponds to $\textbf{cor}$?
|
||||||
|
Back: `||`
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
Tags: c
|
||||||
|
<!--ID: 1707316606007-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Why is $\textbf{cor}$ named the way it is?
|
||||||
|
Back: It is short for **c**onditional **or**.
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708630-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
How is $p \textbf{ cor } q$ written as a conditional?
|
||||||
|
Back: $\textbf{if } p \textbf{ then } T \textbf{ else } q$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708632-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
When can $\textbf{cor}$ evaluate to a non-$U$ value despite being given a $U$ operand?
|
||||||
|
Back: $T \textbf{ cor } U = T$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708633-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
* Associative Laws
|
||||||
|
* $E1 \textbf{ cand } (E2 \textbf{ cand } E3) = (E1 \textbf{ cand } E2) \textbf{ cand } E3$
|
||||||
|
* $E1 \textbf{ cor } (E2 \textbf{ cor } E3) = (E1 \textbf{ cor } E2) \textbf{ cor } E3$
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Which of the short-circuit logical operators do the commutative laws apply to?
|
||||||
|
Back: Neither of them.
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708635-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Which of the short-circuit logical operators do the associative laws apply to?
|
||||||
|
Back: $\textbf{cand}$ and $\textbf{cor}$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708636-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
* Distributive Laws
|
||||||
|
* $E1 \textbf{ cand } (E2 \textbf{ cor } E3) = (E1 \textbf{ cand } E2) \textbf{ cor } (E1 \textbf{ cand } E3)$
|
||||||
|
* $E1 \textbf{ cor } (E2 \textbf{ cand } E3) = (E1 \textbf{ cor } E2) \textbf{ cand } (E1 \textbf{ cor } E3)$
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is the distributive law of e.g. $\textbf{cor}$ over $\textbf{cand}$?
|
||||||
|
Back: $E1 \textbf{ cor } (E2 \textbf{ cand } E3) = (E1 \textbf{ cor } E2) \textbf{ cand } (E1 \textbf{ cor } E3)$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708638-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
* De Morgan's Laws
|
||||||
|
* $\neg (E1 \textbf{ cand } E2) = \neg E1 \textbf{ cor } \neg E2$
|
||||||
|
* $\neg (E1 \textbf{ cor } E2) = \neg E1 \textbf{ cand } \neg E2$
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
Which of the short-circuit logical operators do De Morgan's Laws apply to?
|
||||||
|
Back: $\textbf{cand}$ and $\textbf{cor}$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708640-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
%%ANKI
|
||||||
|
Basic
|
||||||
|
What is De Morgan's Law of e.g. $\textbf{cor}$?
|
||||||
|
Back: $\neg (E1 \textbf{ cor } E2) = \neg E1 \textbf{ cand } \neg E2$
|
||||||
|
Reference: Gries, David. *The Science of Programming*. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.
|
||||||
|
<!--ID: 1707317708642-->
|
||||||
|
END%%
|
||||||
|
|
||||||
|
Gries lists other "Laws" but they don't seem as important to note here. What's worth noting is that the other [[#Equivalence Schemas]] listed above still apply if we can limit operands to just $T$ and $F$.
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
* Avigad, Jeremy. ‘Theorem Proving in Lean’, n.d.
|
* Avigad, Jeremy. ‘Theorem Proving in Lean’, n.d.
|
||||||
|
|
|
@ -132,7 +132,7 @@ END%%
|
||||||
|
|
||||||
%%ANKI
|
%%ANKI
|
||||||
Basic
|
Basic
|
||||||
`^` and `$` belong to what operator category?
|
`^` and `$$` belong to what operator category?
|
||||||
Back: Anchors
|
Back: Anchors
|
||||||
Reference: “POSIX Basic Regular Expressions,” accessed February 4, 2024, [https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions](https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions).
|
Reference: “POSIX Basic Regular Expressions,” accessed February 4, 2024, [https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions](https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions).
|
||||||
<!--ID: 1707050923643-->
|
<!--ID: 1707050923643-->
|
||||||
|
@ -243,7 +243,7 @@ Notation for describing a class of characters specific to a given locale/charact
|
||||||
|
|
||||||
%%ANKI
|
%%ANKI
|
||||||
Basic
|
Basic
|
||||||
What inconsistency do character classes introduce?
|
What portability issue do character classes introduce?
|
||||||
Back: Matching characters are dependent on locale/character set.
|
Back: Matching characters are dependent on locale/character set.
|
||||||
Reference: Robbins, Arnold D. “GAWK: Effective AWK Programming,” October 2023. [https://www.gnu.org/software/gawk/manual/gawk.pdf](https://www.gnu.org/software/gawk/manual/gawk.pdf)
|
Reference: Robbins, Arnold D. “GAWK: Effective AWK Programming,” October 2023. [https://www.gnu.org/software/gawk/manual/gawk.pdf](https://www.gnu.org/software/gawk/manual/gawk.pdf)
|
||||||
<!--ID: 1707050923719-->
|
<!--ID: 1707050923719-->
|
||||||
|
|
Loading…
Reference in New Issue