-
-
Notifications
You must be signed in to change notification settings - Fork 51
feat: implement deret geometri #162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,201 @@ | ||
| /** | ||
| * @brief Program untuk mensimulasikan deret geometri. | ||
| * | ||
| * Program ini menyediakan berbagai overload fungsi untuk menghitung | ||
| * suku ke-n, jumlah n suku pertama, serta memvisualisasikan deret | ||
| * geometri berdasarkan rasio dan suku awal yang diberikan. | ||
| * | ||
| * @details | ||
| * - Mengimplementasikan konsep *three-pair overload*, yaitu hanya satu fungsi | ||
| * utama yang bekerja dengan parameter berbasis iterator, sementara dua overload | ||
| * lainnya (untuk parameter `initializer_list` dan tiga nilai langsung `a, r, | ||
| * n`) hanya berperan sebagai pembungkus (*wrapper*) yang memanggil fungsi utama | ||
| * tersebut. | ||
| * - Dengan pendekatan ini, hanya ada satu sumber logika inti, sehingga | ||
| * memudahkan pemeliharaan dan menghindari duplikasi kode. | ||
| * - Mendukung perhitungan berbasis bilangan bulat (integer-only) | ||
| * sehingga tidak perlu mengkhawatirkan kesalahan presisi floating point. | ||
| * - Menggunakan indeks berbasis 0 (0-based indexing), artinya suku pertama | ||
| * berada pada indeks 0. | ||
| * - Dapat digunakan untuk eksperimen atau pembelajaran konsep deret geometri | ||
| * dengan parameter yang bervariasi. | ||
| * | ||
| * @authors Muh Yusuf | ||
| * @note Program ini bekerja dengan 0-based indexed. | ||
| */ | ||
| #include <cmath> | ||
| #include <concepts> | ||
| #include <cstddef> | ||
| #include <initializer_list> | ||
| #include <iostream> | ||
| #include <iterator> | ||
| #include <ranges> | ||
| #include <sstream> | ||
| #include <string> | ||
| #include <type_traits> | ||
| #include <vector> | ||
| /** | ||
| * @brief Menghitung rasio (r) dari suatu deret geometri. | ||
| * | ||
| * @details | ||
| * Fungsi ini bekerja dengan dua iterator (`first` dan `last`) yang | ||
| * merepresentasikan rentang elemen dalam deret geometri. Nilai rasio ditentukan | ||
| * dengan membagi elemen kedua dengan elemen pertama dari deret tersebut. | ||
| * | ||
| */ | ||
| template <std::input_iterator It> | ||
| auto rasio(It first, It last) | ||
| -> std::common_type_t<std::iter_value_t<It>, std::size_t> { | ||
| using common = std::common_type_t<std::iter_value_t<It>, std::size_t>; | ||
| std::vector<common> deret(first, last); | ||
| if (deret.size() < 2) { | ||
| return *deret.begin(); | ||
| } | ||
| return deret[1] / deret[0]; | ||
| } | ||
| template <std::input_iterator It> | ||
| requires(std::integral<std::iter_value_t<It>>) | ||
| auto rasio(It first, It last, std::size_t pos_1, std::size_t pos_2) | ||
| -> std::common_type_t<std::iter_value_t<It>, std::size_t> { | ||
| std::vector<int> deret(first, last); | ||
| if (deret.size() < 2) { | ||
| return *deret.begin(); // return suku pertama | ||
| } | ||
| using common = std::common_type_t<std::iter_value_t<It>, std::size_t>; | ||
| auto val_pos1 = deret[pos_1]; | ||
| auto val_pos2 = deret[pos_2]; | ||
| common rhs = (pos_1 < pos_2) ? val_pos2 / val_pos1 : val_pos1 / val_pos2; | ||
| double lhs = pos_1 < pos_2 ? pos_2 - 1 : pos_1 - pos_2; | ||
| common result = pow(rhs, 1.0 / lhs); | ||
| return result; | ||
| } | ||
| /** | ||
| * @brief Menghitung suku ke-n dari deret geometri. | ||
| * | ||
| * @details | ||
| * Fungsi ini menerima dua iterator (`first`, `last`) yang menunjuk ke deret | ||
| * bilangan geometri dan sebuah parameter `n` yang menunjukkan suku ke-n yang | ||
| * ingin dihitung. | ||
| * | ||
| * Cara kerja: | ||
| * 1. Menentukan rasio umum deret dengan memanggil fungsi `rasio()`. | ||
| * 2. Mengambil nilai suku pertama (`a`). | ||
| * 3. Menggunakan rumus dasar deret geometri: | ||
| * | ||
| * U_n = a + r^(n - 1) | ||
| * dimana: | ||
| * Un = rumus suku ke-n | ||
| * a = suku pertama | ||
| * r = rasio | ||
| * n = suku yang ingin diketahui | ||
| * Nilai dikembalikan dalam tipe data yang merupakan hasil dari | ||
| * `std::common_type_t` antara nilai iterator dan `std::size_t`. | ||
| */ | ||
| template <std::input_iterator It> | ||
| requires(std::integral<std::iter_value_t<It>>) | ||
| auto suku_keN(It first, It last, std::size_t n) | ||
| -> std::common_type_t<std::iter_value_t<It>, std::size_t> { | ||
| using common = std::common_type_t<std::iter_value_t<It>, std::size_t>; | ||
| common _rasio = rasio(first, last); | ||
| std::vector<common> deret(first, last); | ||
| common res = deret.front() * pow(_rasio, n - 1); | ||
| return res; | ||
| } | ||
| /** | ||
| * @brief Menghasilkan representasi string dari rumus umum suku ke-n deret | ||
| * geometri. | ||
| * | ||
| * @details | ||
| * Fungsi ini menyusun rumus dalam bentuk teks menggunakan nilai suku pertama | ||
| * (`a`) dan rasio (`r`) yang diperoleh dari deret. | ||
| * | ||
| * Rumus yang dihasilkan berbentuk: | ||
| * | ||
| * ``` | ||
| * Un = a * r^(n - 1) | ||
| * ``` | ||
| */ | ||
| template <std::input_iterator It> | ||
| requires(std::integral<std::iter_value_t<It>>) | ||
| std::string rumus_suku_KeN(It first, It last){ | ||
| // using common = std::common_type<std::iter_value_t<It>,std::size_t>; | ||
| using type_iter = std::iter_value_t<It>; | ||
| type_iter a = *first; | ||
| type_iter r = rasio(first, last); | ||
| std::ostringstream oss; | ||
| oss << "Un = " << a << " + " << r << "^n - 1"; | ||
| return oss.str(); | ||
| } | ||
| template <typename T> | ||
| requires(std::integral<T>) | ||
| // jika 2 diketahui 2 suku berurutan | ||
| T rasio(T suku_1, T suku_2) { | ||
| return suku_2 > suku_1 ? suku_2 / suku_1 : suku_1 / suku_2; | ||
| } | ||
| // jika tidak ketahui suku berurutan tetapi diberikan deret | ||
| template <typename T> | ||
| requires(std::integral<T>) | ||
| T rasio(std::initializer_list<T> arr) { | ||
| return rasio(arr.begin(), arr.end()); | ||
| } | ||
| // jika diketahui 2 suku ke n yang tidak beurutan | ||
| template <typename T> | ||
| requires(std::integral<T>) | ||
| auto rasio(std::initializer_list<T> arr, std::size_t pos_1, std::size_t pos_2) | ||
| -> std::common_type_t<T, std::size_t> { | ||
| return rasio(arr.begin(), arr.end(), pos_1, pos_2); | ||
| } | ||
| // jika diketahui deret | ||
| template <std::ranges::input_range arr> | ||
| requires(std::integral<std::ranges::range_value_t<arr>>) | ||
| auto rasio(arr &&R) { | ||
| return rasio(R.begin(), R.end()); | ||
| } | ||
| template <std::ranges::input_range arr> | ||
| requires(std::integral<std::ranges::range_value_t<arr>>) | ||
| auto rasio(arr &&R, std::size_t pos_1, std::size_t pos_2) { | ||
| return rasio(R.begin(), R.end(), pos_1, pos_2); | ||
| } | ||
| template <typename T> | ||
| requires(std::integral<T>) | ||
| auto suku_keN(std::initializer_list<T> arr, std::size_t n) { | ||
| return suku_keN(arr.begin(), arr.end(), n); | ||
| } | ||
| template <std::ranges::input_range arr> | ||
| requires(std::integral<std::ranges::range_value_t<arr>>) | ||
| auto suku_keN(arr &&R, std::size_t n) { | ||
| return suku_keN(R.begin(), R.end(), n); | ||
| } | ||
| template <typename T> | ||
| requires(std::integral<T>) | ||
| std::string rumus_suku_KeN(std::initializer_list<T> arr) { | ||
| return rumus_suku_KeN(arr.begin(), arr.end()); | ||
| } | ||
| template <std::ranges::input_range arr> | ||
| requires(std::integral<std::ranges::range_value_t<arr>>) | ||
| std::string rumus_suku_KeN(arr &&R) { | ||
| return rumus_suku_KeN(R.begin(), R.end()); | ||
| } | ||
| int main() { | ||
| std::cout << "jika hanya diketahui 2 suku berurutan" << std::endl; | ||
| std::cout << "hasil: " << rasio(2, 4) << std::endl; | ||
| std::cout << "jika diketahui 2 suku tidak berurutan(base on index)" << std::endl; | ||
| std::cout << "hasil: " << rasio({2, 4, 8, 16}, 0, 2) << std::endl; | ||
| std::vector<int> a = {3, 6, 12, 24}; | ||
| std::cout << "menggunakan ranges" << std::endl; | ||
| std::cout << rasio(a) << std::endl; | ||
| std::cout << "rumus suku keN" << std::endl; | ||
| std::cout << "rumus: " << rumus_suku_KeN(a) << std::endl; | ||
| // Menggunakan iterator langsung (begin, end) | ||
| std::cout << "[4] Menggunakan iterator langsung\n"; | ||
| std::vector<int> deret1 = {2, 6, 18, 54}; | ||
| std::cout << "rasio(deret1.begin(), deret1.end()) = " | ||
| << rasio(deret1.begin(), deret1.end()) << std::endl; | ||
| // Menghitung nilai suku ke-n (iterator) | ||
| std::cout << "[8] Nilai suku ke-n (iterator)\n"; | ||
| std::vector<int> deret3 = {3, 6, 12, 24}; | ||
| std::cout << "suku_keN(deret3.begin(), deret3.end(), 5) = " | ||
| << suku_keN(deret3.begin(), deret3.end(), 5) << "\n\n"; | ||
| std::cin.get(); | ||
| return 0; | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tidak ada jarak