From e0609d6dafdff7e0f117e8de20a7aeebaa7abfca Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Sat, 8 Nov 2025 20:02:58 +0700 Subject: [PATCH 1/4] plssss --- .../combinatoric.cpp.E6018CF338DAA1FC.idx | Bin 3896 -> 11868 bytes .../combinatoric.hpp.CE279D35FC38B4A8.idx | Bin 3950 -> 10140 bytes src/operation/combinatoric.cpp | 3 +++ 3 files changed, 3 insertions(+) diff --git a/.cache/clangd/index/combinatoric.cpp.E6018CF338DAA1FC.idx b/.cache/clangd/index/combinatoric.cpp.E6018CF338DAA1FC.idx index 160b135d4abfb454be5bda4d90e0f9d50ad1a324..e41e18da5347368073b457ef262b9db8ef049e75 100644 GIT binary patch literal 11868 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 literal 3896 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 literal 3950 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 QFBS96LeEe7Z!p~K|Ad0=%>V!Z diff --git a/src/operation/combinatoric.cpp b/src/operation/combinatoric.cpp index 59df295..8624524 100644 --- a/src/operation/combinatoric.cpp +++ b/src/operation/combinatoric.cpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include namespace imeth::Combinatorics { From f474ae4dbf215e17fdc48a896303614b989c5e06 Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Sat, 8 Nov 2025 20:07:52 +0700 Subject: [PATCH 2/4] cmake branch --- .github/workflows/cmake-multi-platform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index cce3b83..3fe05c8 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -2,7 +2,7 @@ name: CMake Multi-Platform Build on: push: - branches: ["main"] + branches: ["main", "master"] pull_request: branches: ["main"] From b4247ea32dae6e05f3ba6dae27a5387a5eafdcbc Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Sat, 8 Nov 2025 21:04:22 +0700 Subject: [PATCH 3/4] docs: combinatorics. --- docs/SUMMARY.md | 1 + docs/api/operation/README.md | 2 + docs/api/operation/combinatoric.md | 834 +++++++++++++++++++++++++++++ 3 files changed, 837 insertions(+) create mode 100644 docs/api/operation/combinatoric.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 1e4ac5e..70ffab9 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -14,6 +14,7 @@ - [Operation Category](./api/operation/README.md) - [Arithmetic](./api/operation/arithmetic.md) - [Logarithm](./api/operation/logarithm.md) + - [Combinatoric](./api/operation/combinatoric.md) - [Linear Category](./api/linear/README.md) - [Algebra](./api/linear/algebra.md) - [Matrix](./api/linear/matrix.md) diff --git a/docs/api/operation/README.md b/docs/api/operation/README.md index 7e2f252..db203ba 100644 --- a/docs/api/operation/README.md +++ b/docs/api/operation/README.md @@ -6,10 +6,12 @@ The `operation` category contains general mathematical operations including arit - **[Arithmetic](./arithmetic.md)** - Comprehensive arithmetic operations and utilities - **[Logarithm](./logarithm.md)** - Logarithmic operations and exponential equation solving +- **[Combinatoric](./logarithm.md)** - Compilation of combinatoric operations and utilities ## Usage ```c++ #include #include +#include ``` diff --git a/docs/api/operation/combinatoric.md b/docs/api/operation/combinatoric.md new file mode 100644 index 0000000..a0ed7b5 --- /dev/null +++ b/docs/api/operation/combinatoric.md @@ -0,0 +1,834 @@ +# Combinatorics + +The combinatorics chapter provides a comprehensive collection of functions for counting, probability calculations, and set operations. This module is essential for solving problems involving arrangements, selections, and probability. + +```c++ +#include +``` + +## Overview + +Combinatorics is the mathematics of counting. This module helps you answer questions like: +- "How many ways can I arrange these items?" +- "What's the probability of rolling a specific number?" +- "How many different groups can I make?" + +--- + +## Basic Combinatorics + +### Factorial + +```c++ +uint_t factorial(uint_t n); +``` + +Calculates n! (n factorial) = n × (n-1) × (n-2) × ... × 2 × 1 + +**Examples:** +```c++ +factorial(5); // 120 (5 × 4 × 3 × 2 × 1) +factorial(3); // 6 +factorial(0); // 1 (by definition) +factorial(10); // 3,628,800 +``` + +**Real-world:** Number of ways to arrange n items in a line. + +--- + +### Combinations + +```c++ +uint_t combination(uint_t n, uint_t k); +``` + +Calculate C(n,k) or "n choose k" - selecting k items from n items where order doesn't matter. + +**Formula:** C(n,k) = n! / (k! × (n-k)!) + +**Examples:** +```c++ +combination(5, 2); // 10 (choosing 2 from 5) +combination(10, 3); // 120 +combination(52, 5); // 2,598,960 (5-card poker hands) +``` + +**Real-world:** +- Selecting a team of 5 from 12 players +- Choosing 3 toppings from 8 options +- Lottery number selections + +--- + +### Permutations + +```c++ +uint_t permutation(uint_t n, uint_t r); +``` + +Calculate P(n,r) - arranging r items from n items where order matters. + +**Formula:** P(n,r) = n! / (n-r)! + +**Examples:** +```c++ +permutation(5, 2); // 20 (arranging 2 from 5) +permutation(10, 3); // 720 +permutation(8, 8); // 40,320 (all arrangements of 8 items) +``` + +**Real-world:** +- Arranging podium positions (1st, 2nd, 3rd) +- Password possibilities +- Race finishing orders + +--- + +### Combinations with Repetition + +```c++ +uint_t combination_with_repetition(uint_t n, uint_t r); +``` + +Selecting r items from n types where items can be selected multiple times. + +**Formula:** C(n+r-1, r) + +**Examples:** +```c++ +combination_with_repetition(3, 2); // 6 +// Choosing 2 fruits from {apple, banana, orange} +// Possibilities: AA, AB, AC, BB, BC, CC + +combination_with_repetition(5, 3); // 35 +``` + +**Real-world:** +- Buying 5 donuts from 8 flavors (can pick same flavor multiple times) +- Distributing identical items into different boxes + +--- + +### Permutations with Repetition + +```c++ +uint_t permutation_with_repetition(uint_t n, const std::vector& repetitions); +``` + +Arranging items where some items are identical. + +**Formula:** n! / (n₁! × n₂! × ... × nₖ!) + +**Examples:** +```c++ +// Word "MISSISSIPPI" (1M, 4I, 4S, 2P) +std::vector letters = {1, 4, 4, 2}; +permutation_with_repetition(11, letters); // 34,650 + +// Word "BOOK" (1B, 2O, 1K) +std::vector book = {1, 2, 1}; +permutation_with_repetition(4, book); // 12 +``` + +**Real-world:** +- Anagrams of words with repeated letters +- Arranging colored balls where some colors repeat + +--- + +### Full Repetition Permutations + +```c++ +uint_t permutation_full_repetition(uint_t n, uint_t r); +``` + +Number of r-length sequences from n items with unlimited repetition. + +**Formula:** n^r + +**Examples:** +```c++ +permutation_full_repetition(10, 4); // 10,000 (4-digit PIN codes) +permutation_full_repetition(2, 8); // 256 (8-bit binary numbers) +permutation_full_repetition(26, 3); // 17,576 (3-letter combinations) +``` + +**Real-world:** +- Password combinations +- License plate possibilities +- Binary sequences + +--- + +### Circular Permutations + +```c++ +uint_t circular_permutation(uint_t n); +``` + +Arranging n items in a circle (rotations are considered the same). + +**Formula:** (n-1)! + +**Examples:** +```c++ +circular_permutation(5); // 24 (arranging 5 people at a round table) +circular_permutation(4); // 6 +circular_permutation(6); // 120 +``` + +**Real-world:** +- Seating arrangements at a round table +- Necklace bead arrangements +- Round-robin tournament schedules + +--- + +### Permutations with Restrictions + +```c++ +uint_t permutation_with_restriction(uint_t n, uint_t fixed_positions); +``` + +Arrangements where some positions are fixed. + +**Examples:** +```c++ +// 5 items where 2 positions are fixed +permutation_with_restriction(5, 2); // 6 + +// Photo lineup where first and last must be specific people +permutation_with_restriction(8, 2); // 720 +``` + +**Real-world:** +- Arrangements where certain items must be in specific positions +- Queue arrangements with VIP positions reserved + +--- + +## Probability Classes + +### Dice + +Simulate dice rolling probabilities. + +```c++ +Dice dice; +``` + +**Methods:** + +```c++ +double probability_of_number(int target) const; +double probability_of_even() const; +double probability_of_odd() const; +double probability_greater_than(int limit) const; +double probability_less_than(int limit) const; +double probability_between(int min, int max) const; +double probability_sum_two_dice(int target) const; +double probability_sum_n_dice(int target, int n_dice) const; +double probability_all_same(int target, int n_dice) const; +static double probability_all_different(int n_dice); +``` + +**Examples:** +```c++ +Dice dice; + +dice.probability_of_number(6); // 0.1667 (1/6) +dice.probability_of_even(); // 0.5 (3/6) +dice.probability_greater_than(4); // 0.3333 (2/6) +dice.probability_between(3, 5); // 0.5 (3/6) + +// Two dice +dice.probability_sum_two_dice(7); // 0.1667 (highest probability sum) +dice.probability_sum_two_dice(12); // 0.0278 (only 6+6) + +// Multiple dice +dice.probability_all_same(6, 3); // Probability of rolling three 6s +Dice::probability_all_different(3); // All three dice show different numbers +``` + +--- + +### Coin + +Simulate coin flip probabilities. + +```c++ +Coin coin; +``` + +**Methods:** + +```c++ +static double probability_of(char target); +static double probability_consecutive(char target, unsigned int times); +static double probability_at_least_one(char target, unsigned int times); +static double probability_exactly_k(char target, unsigned int k, unsigned int n); +static double probability_more_than_k(char target, unsigned int k, unsigned int n); +static double probability_alternating(unsigned int n); +``` + +**Examples:** +```c++ +Coin::probability_of('H'); // 0.5 +Coin::probability_consecutive('H', 3); // 0.125 (HHH) +Coin::probability_at_least_one('H', 5); // 0.96875 +Coin::probability_exactly_k('H', 3, 5); // P(exactly 3 heads in 5 flips) +Coin::probability_more_than_k('H', 2, 5); // P(more than 2 heads in 5 flips) +Coin::probability_alternating(4); // P(HTHT or THTH) +``` + +--- + +### MarbleBag + +Simulate drawing marbles from a bag. + +```c++ +MarbleBag(unsigned int red_count, unsigned int white_count, unsigned int blue_count = 0); +``` + +**Methods:** + +```c++ +unsigned int total() const; +double probability_single(char color) const; +double probability_two_consecutive(char first, char second) const; +double probability_two_with_replacement(char first, char second) const; +double probability_all_same(char color, unsigned int draws) const; +double probability_at_least_one(char color, unsigned int draws) const; +double probability_exactly_k(char color, unsigned int k, unsigned int draws) const; +``` + +**Examples:** +```c++ +// Bag with 5 red, 3 white, 2 blue marbles +MarbleBag bag(5, 3, 2); + +bag.total(); // 10 +bag.probability_single('r'); // 0.5 (5/10) +bag.probability_two_consecutive('r', 'w'); // Without replacement +bag.probability_two_with_replacement('r', 'w'); // With replacement +bag.probability_all_same('r', 3); // Drawing 3 red in a row +bag.probability_exactly_k('r', 2, 3); // Exactly 2 red in 3 draws +``` + +**Color codes:** 'r' = red, 'w' = white, 'b' = blue + +--- + +### Deck + +Standard 52-card deck probabilities. + +```c++ +Deck deck; +``` + +**Methods:** + +```c++ +static double probability_suit(char suit); +static double probability_red(); +double probability_black() const; +static double probability_face_card(); +static double probability_number_card(); +static double probability_ace(); +static double probability_specific_card(int rank); +static double probability_two_same_suit(); +static double probability_pair(); +static double probability_straight_flush(unsigned int cards); +``` + +**Examples:** +```c++ +Deck::probability_suit('h'); // 0.25 (13/52 hearts) +Deck::probability_red(); // 0.5 +Deck::probability_face_card(); // 0.231 (12/52: J, Q, K) +Deck::probability_ace(); // 0.077 (4/52) +Deck::probability_two_same_suit(); // Drawing 2 cards of same suit +Deck::probability_pair(); // Drawing a pair +``` + +**Suit codes:** 'h' = hearts, 'd' = diamonds, 'c' = clubs, 's' = spades + +--- + +### Spinner + +Simulate probability spinner or roulette wheel. + +```c++ +Spinner(const std::vector& section_values); +``` + +**Methods:** + +```c++ +double probability_of(int value) const; +double probability_greater_than(int limit) const; +double probability_even() const; +double probability_odd() const; +double expected_value() const; +``` + +**Examples:** +```c++ +// Spinner with sections: 1, 2, 3, 2, 4, 2 +std::vector sections = {1, 2, 3, 2, 4, 2}; +Spinner spinner(sections); + +spinner.probability_of(2); // 0.5 (3 out of 6 sections) +spinner.probability_even(); // 0.667 (4/6: 2,2,4,2) +spinner.probability_greater_than(2); // 0.333 (2/6: 3,4) +spinner.expected_value(); // Average value +``` + +--- + +### Lottery + +Calculate lottery winning probabilities. + +```c++ +Lottery(unsigned int total_numbers, unsigned int numbers_drawn); +``` + +**Methods:** + +```c++ +double probability_match_all() const; +double probability_match_k(unsigned int k) const; +double probability_match_at_least_k(unsigned int k) const; +``` + +**Examples:** +```c++ +// 6/49 lottery (pick 6 from 49) +Lottery lottery(49, 6); + +lottery.probability_match_all(); // ~0.00000007 (1 in 13,983,816) +lottery.probability_match_k(3); // Match exactly 3 numbers +lottery.probability_match_at_least_k(4);// Match 4 or more numbers +``` + +--- + +## Probability Functions + +General probability calculation functions. + +### Binomial Probability + +```c++ +double binomial_probability(unsigned int n, unsigned int k, double p); +``` + +Probability of exactly k successes in n trials with probability p. + +**Examples:** +```c++ +// Probability of 3 heads in 5 coin flips +binomial_probability(5, 3, 0.5); // 0.3125 + +// Probability of 2 successes in 10 trials (30% success rate) +binomial_probability(10, 2, 0.3); +``` + +--- + +### Geometric Probability + +```c++ +double geometric_probability(unsigned int k, double p); +``` + +Probability that first success occurs on the k-th trial. + +**Examples:** +```c++ +// Probability first head appears on 3rd flip +geometric_probability(3, 0.5); // 0.125 +``` + +--- + +### Hypergeometric Probability + +```c++ +double hypergeometric_probability(unsigned int N, unsigned int K, + unsigned int n, unsigned int k); +``` + +Drawing without replacement from a finite population. + +**Parameters:** +- N: Total population size +- K: Number of success states in population +- n: Number of draws +- k: Number of observed successes + +--- + +### Basic Probability Operations + +```c++ +double complement_probability(double p); +double union_probability(double p1, double p2, double p_both); +double intersection_probability(double p1, double p2_given_1); +double conditional_probability(double p_both, double p_condition); +``` + +**Examples:** +```c++ +complement_probability(0.3); // 0.7 (1 - 0.3) +union_probability(0.4, 0.5, 0.2); // P(A or B) +intersection_probability(0.6, 0.3); // P(A and B) +conditional_probability(0.15, 0.3); // P(A|B) +``` + +--- + +### Advanced Functions + +```c++ +double total_probability(const std::vector& event_probs, + const std::vector& conditional_probs); +double bayes_theorem(double p_b_given_a, double p_a, double p_b); +double expected_value(const std::vector& values, + const std::vector& probabilities); +double variance(const std::vector& values, + const std::vector& probabilities); +double standard_deviation(const std::vector& values, + const std::vector& probabilities); +``` + +--- + +## Counting Functions + +### Derangement + +```c++ +uint_t derangement(uint_t n); +``` + +Number of permutations where no element appears in its original position. + +**Examples:** +```c++ +derangement(3); // 2 (arrangements where nothing is in original spot) +derangement(4); // 9 +``` + +**Real-world:** Secret Santa where nobody gets their own name. + +--- + +### Stirling Numbers (Second Kind) + +```c++ +uint_t stirling_second_kind(uint_t n, uint_t k); +``` + +Ways to partition n objects into k non-empty subsets. + +--- + +### Catalan Numbers + +```c++ +uint_t catalan_number(uint_t n); +``` + +Sequence appearing in many counting problems. + +**Examples:** +```c++ +catalan_number(3); // 5 +catalan_number(4); // 14 +``` + +**Real-world:** +- Valid parentheses combinations +- Binary tree structures +- Path counting problems + +--- + +### Bell Numbers + +```c++ +uint_t bell_number(uint_t n); +``` + +Number of ways to partition a set of n elements. + +--- + +### Number Sequences + +```c++ +uint_t fibonacci(uint_t n); +uint_t lucas_number(uint_t n); +uint_t triangular_number(uint_t n); +uint_t pentagonal_number(uint_t n); +uint_t hexagonal_number(uint_t n); +``` + +**Examples:** +```c++ +fibonacci(10); // 55 (Fibonacci sequence) +lucas_number(5); // 11 +triangular_number(5); // 15 (1+2+3+4+5) +pentagonal_number(4); // 22 +hexagonal_number(3); // 15 +``` + +--- + +### Dynamic Programming Problems + +```c++ +uint_t ways_to_climb_stairs(unsigned int n, const std::vector& step_sizes); +uint_t ways_to_make_change(unsigned int amount, const std::vector& denominations); +uint_t ways_to_partition(unsigned int n); +uint_t ways_to_partition_into_k(unsigned int n, unsigned int k); +``` + +**Examples:** +```c++ +// Climbing 5 stairs, can take 1 or 2 steps at a time +std::vector steps = {1, 2}; +ways_to_climb_stairs(5, steps); // 8 ways + +// Make 10 cents with {1, 5, 10} cent coins +std::vector coins = {1, 5, 10}; +ways_to_make_change(10, coins); // 4 ways +``` + +--- + +### Pascal's Triangle + +```c++ +std::vector pascal_row(unsigned int row); +``` + +Returns the nth row of Pascal's triangle. + +**Examples:** +```c++ +pascal_row(0); // {1} +pascal_row(1); // {1, 1} +pascal_row(2); // {1, 2, 1} +pascal_row(3); // {1, 3, 3, 1} +pascal_row(4); // {1, 4, 6, 4, 1} +``` + +--- + +## Set Operations + +Template functions for working with sets. + +### Generate Combinations + +```c++ +template +void generate_combinations(const std::vector& items, unsigned int k, + std::vector>& result); +``` + +**Examples:** +```c++ +std::vector items = {1, 2, 3, 4}; +std::vector> result; +generate_combinations(items, 2, result); +// Result: {{1,2}, {1,3}, {1,4}, {2,3}, {2,4}, {3,4}} +``` + +--- + +### Generate Permutations + +```c++ +template +void generate_permutations(const std::vector& items, + std::vector>& result); +``` + +--- + +### Generate Subsets + +```c++ +template +void generate_subsets(const std::vector& items, + std::vector>& result); +``` + +Generates all possible subsets (power set). + +--- + +### Set Operations + +```c++ +template +bool is_subset(const std::vector& subset, const std::vector& set); + +template +void set_union(const std::vector& set1, const std::vector& set2, + std::vector& result); + +template +void set_intersection(const std::vector& set1, const std::vector& set2, + std::vector& result); + +template +void set_difference(const std::vector& set1, const std::vector& set2, + std::vector& result); + +template +void symmetric_difference(const std::vector& set1, const std::vector& set2, + std::vector& result); + +template +void cartesian_product(const std::vector& set1, const std::vector& set2, + std::vector>& result); +``` + +--- + +## Sequences + +### Arithmetic Sequences + +```c++ +void arithmetic_sequence(uint_t first, uint_t diff, unsigned int terms, + std::vector& result); +uint_t arithmetic_sum(uint_t first, uint_t last, unsigned int terms); +uint_t nth_term_arithmetic(uint_t first, uint_t diff, unsigned int n); +``` + +**Examples:** +```c++ +std::vector seq; +arithmetic_sequence(2, 3, 5, seq); // {2, 5, 8, 11, 14} + +arithmetic_sum(2, 14, 5); // 40 +nth_term_arithmetic(2, 3, 5); // 14 +``` + +--- + +### Geometric Sequences + +```c++ +void geometric_sequence(uint_t first, uint_t ratio, unsigned int terms, + std::vector& result); +uint_t geometric_sum(uint_t first, uint_t ratio, unsigned int terms); +uint_t nth_term_geometric(uint_t first, uint_t ratio, unsigned int n); +``` + +**Examples:** +```c++ +std::vector seq; +geometric_sequence(2, 3, 5, seq); // {2, 6, 18, 54, 162} + +geometric_sum(2, 3, 5); // 242 +nth_term_geometric(2, 3, 5); // 162 +``` + +--- + +## Graph Theory + +### Graph Functions + +```c++ +uint_t complete_graph_edges(unsigned int vertices); +uint_t tree_edges(unsigned int vertices); +uint_t bipartite_complete_edges(unsigned int set1_size, unsigned int set2_size); +uint_t handshake_lemma(const std::vector& degrees); +bool is_graphical_sequence(std::vector degrees); +uint_t chromatic_polynomial_complete(unsigned int n, unsigned int k); +``` + +**Examples:** +```c++ +complete_graph_edges(5); // 10 (complete graph K5) +tree_edges(10); // 9 (tree with 10 vertices) +bipartite_complete_edges(3, 4); // 12 (K3,4) +``` + +--- + +## Complete Example + +```c++ +#include +#include + +int main() { + using namespace imeth::Combinatorics; + + // Basic combinatorics + std::cout << "5! = " << factorial(5) << "\n"; // 120 + std::cout << "C(10,3) = " << combination(10, 3) << "\n"; // 120 + std::cout << "P(5,2) = " << permutation(5, 2) << "\n"; // 20 + + // Probability with dice + Probability::Dice dice; + std::cout << "P(rolling 6) = " << dice.probability_of_number(6) << "\n"; + std::cout << "P(sum of 7 with 2 dice) = " + << dice.probability_sum_two_dice(7) << "\n"; + + // Marble bag + Probability::MarbleBag bag(5, 3, 2); // 5 red, 3 white, 2 blue + std::cout << "P(red marble) = " << bag.probability_single('r') << "\n"; + + // Counting problems + std::cout << "Fibonacci(10) = " << Counting::fibonacci(10) << "\n"; + std::cout << "5th Catalan number = " << Counting::catalan_number(5) << "\n"; + + // Sequences + std::vector arithmetic; + Sequences::arithmetic_sequence(1, 3, 6, arithmetic); + std::cout << "Arithmetic sequence: "; + for (auto n : arithmetic) std::cout << n << " "; // 1 4 7 10 13 16 + std::cout << "\n"; + + return 0; +} +``` + +--- + +## Tips + +- **Combinations vs Permutations**: If order matters, use permutations; if not, use combinations +- **With/Without Replacement**: Affects probability calculations significantly +- **Large Factorials**: Be aware of overflow with large numbers +- **Probability Range**: All probabilities are between 0 and 1 +- **Set Operations**: Useful for working with groups and collections + +--- + +## Quick Reference + +| Problem Type | Function | Example | +|-------------|----------|---------| +| Choose k from n | `combination(n, k)` | Teams, lottery | +| Arrange k from n | `permutation(n, r)` | Races, passwords | +| Repeated choices | `combination_with_repetition` | Donuts, ice cream | +| Round table | `circular_permutation(n)` | Seating | +| Dice probability | `Dice::probability_*` | Games | +| Card probability | `Deck::probability_*` | Poker, blackjack | +| Stairs problem | `ways_to_climb_stairs` | DP problems | +| Make change | `ways_to_make_change` | Coin problems | \ No newline at end of file From d5bf33a85cb59430a8909d3bf382cdb409920017 Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Sat, 8 Nov 2025 21:25:24 +0700 Subject: [PATCH 4/4] fix(*): swapping and removing features. --- include/imeth/operation/arithmetic.hpp | 12 ++- include/imeth/operation/combinatoric.hpp | 4 - src/operation/arithmetic.cpp | 111 ++++++++++++----------- src/operation/combinatoric.cpp | 17 ---- tests/main.cpp | 8 +- 5 files changed, 70 insertions(+), 82 deletions(-) diff --git a/include/imeth/operation/arithmetic.hpp b/include/imeth/operation/arithmetic.hpp index db0c82f..52f1e76 100644 --- a/include/imeth/operation/arithmetic.hpp +++ b/include/imeth/operation/arithmetic.hpp @@ -3,6 +3,8 @@ namespace imeth { namespace Arithmetic { + using uint_t = unsigned long long; + // Basic Operations double add(double a, double b); double subtract(double a, double b); @@ -61,11 +63,13 @@ namespace Arithmetic { double distance2D(double x1, double y1, double x2, double y2); double pythagorean(double a, double b); // Returns hypotenuse c - // Temperature Conversions - double celsiusToFahrenheit(double celsius); - double fahrenheitToCelsius(double fahrenheit); - // Simple Interest double simpleInterest(double principal, double rate, double time); + + // Sequences + void sequence(uint_t first, uint_t diff, unsigned int terms, + std::vector& result); + uint_t sequence_sum(uint_t first, uint_t last, unsigned int terms); + uint_t nth_term(uint_t first, uint_t diff, unsigned int n); }; // namespace arithmetic } // namespace imeth diff --git a/include/imeth/operation/combinatoric.hpp b/include/imeth/operation/combinatoric.hpp index 238fea2..319e30f 100644 --- a/include/imeth/operation/combinatoric.hpp +++ b/include/imeth/operation/combinatoric.hpp @@ -190,13 +190,9 @@ namespace imeth::Combinatorics { } namespace Sequences { - void arithmetic_sequence(uint_t first, uint_t diff, unsigned int terms, - std::vector& result); void geometric_sequence(uint_t first, uint_t ratio, unsigned int terms, std::vector& result); - uint_t arithmetic_sum(uint_t first, uint_t last, unsigned int terms); uint_t geometric_sum(uint_t first, uint_t ratio, unsigned int terms); - uint_t nth_term_arithmetic(uint_t first, uint_t diff, unsigned int n); uint_t nth_term_geometric(uint_t first, uint_t ratio, unsigned int n); } diff --git a/src/operation/arithmetic.cpp b/src/operation/arithmetic.cpp index fd8c6f5..7d6ec69 100644 --- a/src/operation/arithmetic.cpp +++ b/src/operation/arithmetic.cpp @@ -2,22 +2,22 @@ #include #include -namespace imeth { +namespace imeth::Arithmetic { // Basic Operations -double Arithmetic::add(double a, double b) { +double add(double a, double b) { return a + b; } -double Arithmetic::subtract(double a, double b) { +double subtract(double a, double b) { return a - b; } -double Arithmetic::multiply(double a, double b) { +double multiply(double a, double b) { return a * b; } -double Arithmetic::divide(double a, double b) { +double divide(double a, double b) { if (b == 0) { throw std::invalid_argument("Cannot divide by zero"); } @@ -25,7 +25,7 @@ double Arithmetic::divide(double a, double b) { } // Power and Roots -double Arithmetic::power(double base, int exponent) { +double power(double base, int exponent) { double result = 1.0; for (int i = 0; i < exponent; i++) { result *= base; @@ -33,7 +33,7 @@ double Arithmetic::power(double base, int exponent) { return result; } -double Arithmetic::squareRoot(double n) { +double squareRoot(double n) { if (n < 0) { throw std::invalid_argument("Cannot take square root of negative number"); } @@ -42,7 +42,7 @@ double Arithmetic::squareRoot(double n) { return z; } -double Arithmetic::cubeRoot(double n) { +double cubeRoot(double n) { if (n == 0) return 0; bool negative = n < 0; if (negative) n = -n; @@ -61,53 +61,53 @@ double Arithmetic::cubeRoot(double n) { } // Absolute Value and Sign -double Arithmetic::absolute(double n) { +double absolute(double n) { return n < 0 ? -n : n; } -int Arithmetic::absolute(int n) { +int absolute(int n) { return n < 0 ? -n : n; } -int Arithmetic::sign(double n) { +int sign(double n) { if (n > 0) return 1; if (n < 0) return -1; return 0; } // Remainders and Divisibility -int Arithmetic::remainder(int a, int b) { +int remainder(int a, int b) { if (b == 0) { throw std::invalid_argument("Cannot find remainder with divisor of zero"); } return a % b; } -bool Arithmetic::isDivisible(int a, int b) { +bool isDivisible(int a, int b) { if (b == 0) return false; return (a % b) == 0; } // Percentages -double Arithmetic::percentOf(double percent, double total) { +double percentOf(double percent, double total) { return (percent / 100.0) * total; } -double Arithmetic::whatPercent(double part, double total) { +double whatPercent(double part, double total) { if (total == 0) { throw std::invalid_argument("Total cannot be zero"); } return (part / total) * 100.0; } -double Arithmetic::percentIncrease(double original, double newValue) { +double percentIncrease(double original, double newValue) { if (original == 0) { throw std::invalid_argument("Original value cannot be zero"); } return ((newValue - original) / original) * 100.0; } -double Arithmetic::percentDecrease(double original, double newValue) { +double percentDecrease(double original, double newValue) { if (original == 0) { throw std::invalid_argument("Original value cannot be zero"); } @@ -115,14 +115,14 @@ double Arithmetic::percentDecrease(double original, double newValue) { } // Averages and Statistics -double Arithmetic::average(const std::vector& numbers) { +double average(const std::vector& numbers) { if (numbers.empty()) { throw std::invalid_argument("Cannot find average of empty list"); } return sum(numbers) / numbers.size(); } -double Arithmetic::sum(const std::vector& numbers) { +double sum(const std::vector& numbers) { double total = 0; for (const double n : numbers) { total += n; @@ -130,25 +130,25 @@ double Arithmetic::sum(const std::vector& numbers) { return total; } -double Arithmetic::minimum(const std::vector& numbers) { +double minimum(const std::vector& numbers) { if (numbers.empty()) { throw std::invalid_argument("Cannot find minimum of empty list"); } return *std::ranges::min_element(numbers); } -double Arithmetic::maximum(const std::vector& numbers) { +double maximum(const std::vector& numbers) { if (numbers.empty()) { throw std::invalid_argument("Cannot find maximum of empty list"); } return *std::ranges::max_element(numbers); } -double Arithmetic::range(const std::vector& numbers) { +double range(const std::vector& numbers) { return maximum(numbers) - minimum(numbers); } -double Arithmetic::median(std::vector numbers) { +double median(std::vector numbers) { if (numbers.empty()) { throw std::invalid_argument("Cannot find median of empty list"); } @@ -166,7 +166,7 @@ double Arithmetic::median(std::vector numbers) { } // Fractions -double Arithmetic::addFractions(const double num1, const double den1, const double num2, const double den2) { +double addFractions(const double num1, const double den1, const double num2, const double den2) { if (den1 == 0 || den2 == 0) { throw std::invalid_argument("Denominator cannot be zero"); } @@ -177,7 +177,7 @@ double Arithmetic::addFractions(const double num1, const double den1, const doub return (newNum1 + newNum2) / commonDen; } -double Arithmetic::subtractFractions(const double num1, const double den1, const double num2, const double den2) { +double subtractFractions(const double num1, const double den1, const double num2, const double den2) { if (den1 == 0 || den2 == 0) { throw std::invalid_argument("Denominator cannot be zero"); } @@ -187,14 +187,14 @@ double Arithmetic::subtractFractions(const double num1, const double den1, const return (newNum1 - newNum2) / commonDen; } -double Arithmetic::multiplyFractions(const double num1, const double den1, const double num2, const double den2) { +double multiplyFractions(const double num1, const double den1, const double num2, const double den2) { if (den1 == 0 || den2 == 0) { throw std::invalid_argument("Denominator cannot be zero"); } return (num1 * num2) / (den1 * den2); } -double Arithmetic::divideFractions(const double num1, const double den1, const double num2, const double den2) { +double divideFractions(const double num1, const double den1, const double num2, const double den2) { if (den1 == 0 || den2 == 0 || num2 == 0) { throw std::invalid_argument("Denominator cannot be zero and cannot divide by zero"); } @@ -202,7 +202,7 @@ double Arithmetic::divideFractions(const double num1, const double den1, const d } // Rounding -double Arithmetic::roundToNearest(double n) { +double roundToNearest(const double n) { if (n >= 0) { return static_cast(static_cast(n + 0.5)); } else { @@ -211,37 +211,37 @@ double Arithmetic::roundToNearest(double n) { // this can give incorrect results... Do I have to wrap lround() from cmath here????? } -double Arithmetic::roundUp(double n) { - auto intPart = static_cast(n); +double roundUp(const double n) { + const auto intPart = static_cast(n); if (n > 0 && n > static_cast(intPart)) { return static_cast(intPart + 1); } return static_cast(intPart); } -double Arithmetic::roundDown(double n) { - auto intPart = static_cast(n); +double roundDown(const double n) { + const auto intPart = static_cast(n); if (n < 0 && n < static_cast(intPart)) { return static_cast(intPart - 1); } return static_cast(intPart); } -double Arithmetic::roundToDecimalPlaces(double n, int places) { - double multiplier = power(10.0, places); +double roundToDecimalPlaces(const double n, const int places) { + const double multiplier = power(10.0, places); return roundToNearest(n * multiplier) / multiplier; } // Number Properties -bool Arithmetic::isEven(int n) { +bool isEven(const int n) { return n % 2 == 0; } -bool Arithmetic::isOdd(int n) { +bool isOdd(const int n) { return n % 2 != 0; } -bool Arithmetic::isPrime(int n) { +bool isPrime(const int n) { if (n <= 1) return false; if (n == 2) return true; if (n % 2 == 0) return false; @@ -253,7 +253,7 @@ bool Arithmetic::isPrime(int n) { return true; } -int Arithmetic::greatestCommonDivisor(int a, int b) { +int greatestCommonDivisor(int a, int b) { a = absolute(a); b = absolute(b); @@ -265,33 +265,42 @@ int Arithmetic::greatestCommonDivisor(int a, int b) { return a; } -int Arithmetic::leastCommonMultiple(int a, int b) { +int leastCommonMultiple(const int a, const int b) { if (a == 0 || b == 0) return 0; return absolute(a * b) / greatestCommonDivisor(a, b); } // Distance and Pythagorean -double Arithmetic::distance2D(double x1, double y1, double x2, double y2) { - double dx = x2 - x1; - double dy = y2 - y1; +double distance2D(const double x1, const double y1, const double x2, const double y2) { + const double dx = x2 - x1; + const double dy = y2 - y1; return squareRoot(dx * dx + dy * dy); } -double Arithmetic::pythagorean(double a, double b) { +double pythagorean(const double a, const double b) { return squareRoot(a * a + b * b); } -// Temperature Conversions -double Arithmetic::celsiusToFahrenheit(double celsius) { - return (celsius * 9.0 / 5.0) + 32.0; +// Simple Interest +double simpleInterest(const double principal, const double rate, const double time) { + return principal * (rate / 100.0) * time; } -double Arithmetic::fahrenheitToCelsius(double fahrenheit) { - return (fahrenheit - 32.0) * 5.0 / 9.0; +// Sequnces +void sequence(const uint_t first, const uint_t diff, unsigned int terms, std::vector& result) { + result.clear(); + result.reserve(terms); + for (unsigned int i = 0; i < terms; ++i) { + result.push_back(first + i * diff); + } } -// Simple Interest -double Arithmetic::simpleInterest(double principal, double rate, double time) { - return principal * (rate / 100.0) * time; +uint_t sequence_sum(const uint_t first, const uint_t last, const unsigned int terms) { + return terms * (first + last) / 2; +} + +uint_t nth_term(const uint_t first, const uint_t diff, const unsigned int n) { + return first + (n - 1) * diff; } + } // namespace imeth diff --git a/src/operation/combinatoric.cpp b/src/operation/combinatoric.cpp index 8624524..6ae408c 100644 --- a/src/operation/combinatoric.cpp +++ b/src/operation/combinatoric.cpp @@ -821,15 +821,6 @@ namespace imeth::Combinatorics { } namespace Sequences { - void arithmetic_sequence(uint_t first, uint_t diff, unsigned int terms, - std::vector& result) { - result.clear(); - result.reserve(terms); - for (unsigned int i = 0; i < terms; ++i) { - result.push_back(first + i * diff); - } - } - void geometric_sequence(uint_t first, uint_t ratio, unsigned int terms, std::vector& result) { result.clear(); @@ -841,10 +832,6 @@ namespace imeth::Combinatorics { } } - uint_t arithmetic_sum(uint_t first, uint_t last, unsigned int terms) { - return terms * (first + last) / 2; - } - uint_t geometric_sum(uint_t first, uint_t ratio, unsigned int terms) { if (ratio == 1) return first * terms; uint_t power = 1; @@ -854,10 +841,6 @@ namespace imeth::Combinatorics { return first * (power - 1) / (ratio - 1); } - uint_t nth_term_arithmetic(uint_t first, uint_t diff, unsigned int n) { - return first + (n - 1) * diff; - } - uint_t nth_term_geometric(uint_t first, uint_t ratio, unsigned int n) { uint_t result = first; for (unsigned int i = 1; i < n; ++i) { diff --git a/tests/main.cpp b/tests/main.cpp index 8c91291..d3237b9 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -54,7 +54,7 @@ int main() { std::cout << "20 is what % of 50? = " << imeth::Arithmetic::whatPercent(20, 50) << "%\n\n"; // Statistics - std::vector grades = {85, 90, 78, 92, 88}; + const std::vector grades = {85, 90, 78, 92, 88}; std::cout << "Grades: 85, 90, 78, 92, 88\n"; std::cout << "Average: " << imeth::Arithmetic::average(grades) << "\n"; std::cout << "Median: " << imeth::Arithmetic::median(grades) << "\n"; @@ -66,12 +66,8 @@ int main() { std::cout << "Is 20 even? " << (imeth::Arithmetic::isEven(20) ? "Yes" : "No") << "\n"; std::cout << "GCD of 48 and 18 = " << imeth::Arithmetic::greatestCommonDivisor(48, 18) << "\n\n"; - // Temperature - std::cout << "25°C in Fahrenheit = " << imeth::Arithmetic::celsiusToFahrenheit(25) << "°F\n"; - // Quadratic equation - auto result = imeth::QuadraticEquation::solve(1, -5, 6); // x² - 5x + 6 = 0 - if (std::holds_alternative>(result)) { + if (auto result = imeth::QuadraticEquation::solve(1, -5, 6); std::holds_alternative>(result)) { auto [x1, x2] = std::get>(result); std::cout << "x1 = " << x1 << ", x2 = " << x2 << "\n"; }