From 5fa34dec1972cb0c7a7cf0722bce5524da7f71b9 Mon Sep 17 00:00:00 2001 From: arfy slowy Date: Thu, 24 Oct 2024 09:56:42 +0700 Subject: [PATCH] feat: menambahkan konsep matriks (#323) * feat: menambahkan konsep matriks Signed-off-by: slowy07 * update DIRECTORY.md * fix: supressing lgtm dan flake8 Signed-off-by: slowy07 * fix(ci): issue commit check untuk ci update direktori Signed-off-by: slowy07 --------- Signed-off-by: slowy07 Co-authored-by: github-actions --- .github/workflows/directory.yml | 2 +- DIRECTORY.md | 4 ++ algorithm/searching/_types.py | 10 ++- algorithm/searching/binary_search.py | 10 ++- matrix/median_matriks.py | 32 ++++++++++ matrix/pencarian_biner_matrix.py | 96 ++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 matrix/median_matriks.py create mode 100644 matrix/pencarian_biner_matrix.py diff --git a/.github/workflows/directory.yml b/.github/workflows/directory.yml index 795c7c76..39e5cf20 100644 --- a/.github/workflows/directory.yml +++ b/.github/workflows/directory.yml @@ -16,5 +16,5 @@ jobs: - name: Update DIRECTORY.md run: | git add DIRECTORY.md - git commit -am "update DIRECTORY.md" || true + git commit -am "docs: update DIRECTORY.md" || true git push --force origin HEAD:$GITHUB_REF || true diff --git a/DIRECTORY.md b/DIRECTORY.md index ceb83911..43155079 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -293,6 +293,10 @@ * [Volume](https://github.com/bellshade/Python/blob/main/math/volume.py) * [Zellers Congruence](https://github.com/bellshade/Python/blob/main/math/zellers_congruence.py) +## Matrix + * [Median Matriks](https://github.com/bellshade/Python/blob/main/matrix/median_matriks.py) + * [Pencarian Biner Matrix](https://github.com/bellshade/Python/blob/main/matrix/pencarian_biner_matrix.py) + ## Object Oriented * Advance * Pycode diff --git a/algorithm/searching/_types.py b/algorithm/searching/_types.py index 087315f0..4dda9bb1 100644 --- a/algorithm/searching/_types.py +++ b/algorithm/searching/_types.py @@ -8,6 +8,12 @@ @runtime_checkable class SizedIndexable(Iterable[T], Protocol[T]): @overload - def __getitem__(self, key: slice) -> SizedIndexable[T]: ... + def __getitem__(self, key: slice) -> SizedIndexable[T]: + """ + Hanya untuk suppress LGTM alert + """ - def __len__(self) -> int: ... + def __len__(self) -> int: + """ + hanya untuk supress LGTM alert + """ diff --git a/algorithm/searching/binary_search.py b/algorithm/searching/binary_search.py index e5717435..e3cd6770 100644 --- a/algorithm/searching/binary_search.py +++ b/algorithm/searching/binary_search.py @@ -34,12 +34,18 @@ class Comparable(Protocol): - def __lt__(self, other: Any) -> bool: ... + def __lt__(self, other: Any) -> bool: + """ + Hanya untuk supress LGTM alert + """ def __le__(self, other: Any) -> bool: """Hanya untuk suppress LGTM alert.""" - def __gt__(self, other: Any) -> bool: ... + def __gt__(self, other: Any) -> bool: + """ + Hanya untuk supress LGTM alert + """ def __ge__(self, other: Any) -> bool: """Hanya untuk suppress LGTM alert.""" diff --git a/matrix/median_matriks.py b/matrix/median_matriks.py new file mode 100644 index 00000000..948cf093 --- /dev/null +++ b/matrix/median_matriks.py @@ -0,0 +1,32 @@ +def median(matriks: list[list[int]]) -> int: + """ + menghitung nilai dari median dari sebuah matriks + yang sudah diurutkan + + Parameter: + matriks(list[list[int]]): matriks 2D yang berisi bilangan + bulat + + Contoh: + >>> matriks = [[1, 3, 5], [2, 6, 9], [3, 6, 9]] + >>> median(matriks) + 5 + >>> matriks = [[1, 2, 3], [4, 5, 6]] + >>> median(matriks) + 3 + """ + # flatten matriks 2D jadi list 1D yang terurut + linear = sorted(angka for baris in matriks for angka in baris) + + # hitung indeks tengah untuk menemukan median + tengah = (len(linear) - 1) // 2 + + # return hasil dari nilai median + return linear[tengah] + + +if __name__ == "__main__": + import doctest + + # jalankan doctesting + doctest.testmod() diff --git a/matrix/pencarian_biner_matrix.py b/matrix/pencarian_biner_matrix.py new file mode 100644 index 00000000..3f2d96af --- /dev/null +++ b/matrix/pencarian_biner_matrix.py @@ -0,0 +1,96 @@ +def pencarian_biner(array: list, batas_bawah: int, batas_atas: int, nilai: int) -> int: + """ + fungsi ini menjalankan pencarian biner pada array 1D dan + mengembalikan -1 jika nilai tidak ditemukan + + Parameter: + array(list): array 1D yang sudah diurutkan + nilai(int): nilai yang dicari dalam array + + Contoh: + >>> matriks = [1, 4,7, 11, 15] + >>> pencarian_biner(matriks, 0, len(matriks) - 1, 1) + 0 + >>> pencarian_biner(matriks, 0, len(matriks) - 1, 23) + -1 + """ + # hitung indeks tengah dari array + tengah = int((batas_bawah + batas_atas) // 2) + + # jika nilai di indeks sama dengan nilai yang dicari + # return indeks + if array[tengah] == nilai: + return tengah + + # jika batas bawah sudah sama atau lebih dari batas atas + # kembalikan -1 (nilai tidak ada) + if batas_bawah >= batas_atas: + return -1 + + # jikai nilai di indeks tengah lebih kecil dari nilai yang + # dicari, lakukan pencarian biner pada separuh kanan + if array[tengah] < nilai: + return pencarian_biner(array, tengah + 1, batas_atas, nilai) + + # jika nilai di indeks tengah lebih besar lakukan pencarian biner + # pada separuh kiri + else: + return pencarian_biner(array, batas_bawah, tengah - 1, nilai) + + +def pencarian_matriks_biner(nilai: int, matriks: list) -> list: + """ + fungsi ini akan menjalankan iterasi pada matriks 2D dan memanggil + pencarian_biner pada setiap baris matriks, return [-1, -1] jika + nilai tidak ditemukan + + Parameter: + nilai(int): nilai yang dicari dalam matriks + matriks(list): matriks 2D yang sudah diurutkan + + Contoh: + >>> matriks = [[1, 4, 5, 11, 15], + ... [2, 5, 8, 12, 19], + ... [3, 6, 9, 16, 22], + ... [10, 13, 14, 17, 24], + ... [18, 21, 23, 26, 30]] + >>> target = 1 + >>> pencarian_matriks_biner(target, matriks) + [0, 0] + >>> target = 34 + >>> pencarian_matriks_biner(target, matriks) + [-1, -1] + """ + + # inisialisasi indeks baris + indeks = 0 + + # jika nilai pertama di baris pertama sama dengan nilai yang dicari + # return indeks [0, 0] + if matriks[indeks][0] == nilai: + return [indeks, 0] + + # lakukan iterasi pada matriks selama indeks valid dan nilai di kolom pertama + # lebih kecli dari nilai yang dicari + while indeks < len(matriks) and matriks[indeks][0] < nilai: + # cari biner pada baris saat ini + hasil_pencarian = pencarian_biner( + matriks[indeks], 0, len(matriks[indeks]) - 1, nilai + ) + + # jika nilai ditemukan, retunr indeks baris dan kolom + if hasil_pencarian != -1: + return [indeks, hasil_pencarian] + + # pindah ke baris berikutnya + indeks += 1 + + # jika tidak ditemukan maka return [-1, -1] + return [-1, -1] + + +if __name__ == "__main__": + import doctest + + # jalankan doctesting + doctest.testmod()