├── .clang-format ├── .clang-tidy ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── feature_request.yml │ └── other.yml ├── pull_request_template.md └── workflows │ ├── approved-label.yml │ ├── awesome_workflow.yml │ ├── codeql.yml │ ├── directory_writer.yml │ ├── gh-pages.yml │ └── stale.yml ├── .gitignore ├── .gitpod.dockerfile ├── .gitpod.yml ├── .vscode └── settings.json ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CodingGuidelines.md ├── DIRECTORY.md ├── LICENSE ├── README.md ├── REVIEWER_CODE.md ├── backtracking ├── CMakeLists.txt ├── generate_parentheses.cpp ├── graph_coloring.cpp ├── knight_tour.cpp ├── magic_sequence.cpp ├── minimax.cpp ├── n_queens.cpp ├── n_queens_all_solution_optimised.cpp ├── nqueen_print_all_solutions.cpp ├── rat_maze.cpp ├── subarray_sum.cpp ├── subset_sum.cpp ├── sudoku_solver.cpp └── wildcard_matching.cpp ├── bit_manipulation ├── CMakeLists.txt ├── count_bits_flip.cpp ├── count_of_set_bits.cpp ├── count_of_trailing_ciphers_in_factorial_n.cpp ├── find_non_repeating_number.cpp ├── gray_code.cpp ├── hamming_distance.cpp ├── next_higher_number_with_same_number_of_set_bits.cpp ├── power_of_2.cpp ├── set_kth_bit.cpp └── travelling_salesman_using_bit_manipulation.cpp ├── ciphers ├── CMakeLists.txt ├── a1z26_cipher.cpp ├── atbash_cipher.cpp ├── base64_encoding.cpp ├── caesar_cipher.cpp ├── elliptic_curve_key_exchange.cpp ├── hill_cipher.cpp ├── morse_code.cpp ├── uint128_t.hpp ├── uint256_t.hpp ├── vigenere_cipher.cpp └── xor_cipher.cpp ├── cpu_scheduling_algorithms ├── CMakeLists.txt ├── fcfs_scheduling.cpp └── non_preemptive_sjf_scheduling.cpp ├── data_structures ├── CMakeLists.txt ├── avltree.cpp ├── binary_search_tree.cpp ├── binary_search_tree2.cpp ├── binaryheap.cpp ├── bloom_filter.cpp ├── circular_queue_using_linked_list.cpp ├── cll │ ├── CMakeLists.txt │ ├── cll.cpp │ ├── cll.h │ └── main_cll.cpp ├── disjoint_set.cpp ├── doubly_linked_list.cpp ├── dsu_path_compression.cpp ├── dsu_union_rank.cpp ├── linked_list.cpp ├── linkedlist_implentation_usingarray.cpp ├── list_array.cpp ├── morrisinorder.cpp ├── node.hpp ├── queue.hpp ├── queue_using_array.cpp ├── queue_using_array2.cpp ├── queue_using_linked_list.cpp ├── queue_using_linkedlist.cpp ├── queue_using_two_stacks.cpp ├── rb_tree.cpp ├── reverse_a_linked_list.cpp ├── segment_tree.cpp ├── skip_list.cpp ├── sparse_table.cpp ├── stack.hpp ├── stack_using_array.cpp ├── stack_using_linked_list.cpp ├── stack_using_queue.cpp ├── student.txt ├── test_queue.cpp ├── test_stack.cpp ├── test_stack_students.cpp ├── treap.cpp ├── tree.cpp ├── tree_234.cpp ├── trie_modern.cpp ├── trie_tree.cpp └── trie_using_hashmap.cpp ├── divide_and_conquer ├── CMakeLists.txt ├── karatsuba_algorithm_for_fast_multiplication.cpp └── strassen_matrix_multiplication.cpp ├── doc ├── Doxyfile ├── assets │ ├── favicon.svg │ └── project_logo.png ├── html │ └── header.html └── styles │ └── doxygen-awesome.css ├── dynamic_programming ├── 0_1_knapsack.cpp ├── CMakeLists.txt ├── abbreviation.cpp ├── armstrong_number_templated.cpp ├── bellman_ford.cpp ├── catalan_numbers.cpp ├── coin_change.cpp ├── coin_change_topdown.cpp ├── cut_rod.cpp ├── edit_distance.cpp ├── egg_dropping_puzzle.cpp ├── fibonacci_bottom_up.cpp ├── floyd_warshall.cpp ├── house_robber.cpp ├── kadane.cpp ├── longest_common_string.cpp ├── longest_common_subsequence.cpp ├── longest_increasing_subsequence.cpp ├── longest_increasing_subsequence_nlogn.cpp ├── longest_palindromic_subsequence.cpp ├── matrix_chain_multiplication.cpp ├── maximum_circular_subarray.cpp ├── minimum_edit_distance.cpp ├── palindrome_partitioning.cpp ├── partition_problem.cpp ├── searching_of_element_in_dynamic_array.cpp ├── shortest_common_supersequence.cpp ├── subset_sum_dynamic.cpp ├── trapped_rainwater.cpp ├── tree_height.cpp ├── unbounded_0_1_knapsack.cpp └── word_break.cpp ├── games ├── CMakeLists.txt └── memory_game.cpp ├── geometry ├── CMakeLists.txt ├── graham_scan_algorithm.cpp ├── graham_scan_functions.hpp ├── jarvis_algorithm.cpp └── line_segment_intersection.cpp ├── graph ├── CMakeLists.txt ├── bidirectional_dijkstra.cpp ├── breadth_first_search.cpp ├── bridge_finding_with_tarjan_algorithm.cpp ├── connected_components.cpp ├── connected_components_with_dsu.cpp ├── cycle_check_directed_graph.cpp ├── depth_first_search.cpp ├── depth_first_search_with_stack.cpp ├── dijkstra.cpp ├── hamiltons_cycle.cpp ├── hopcroft_karp.cpp ├── is_graph_bipartite.cpp ├── is_graph_bipartite2.cpp ├── kosaraju.cpp ├── kruskal.cpp ├── lowest_common_ancestor.cpp ├── max_flow_with_ford_fulkerson_and_edmond_karp_algo.cpp ├── prim.cpp ├── topological_sort.cpp ├── topological_sort_by_kahns_algo.cpp └── travelling_salesman_problem.cpp ├── graphics ├── CMakeLists.txt └── spirograph.cpp ├── greedy_algorithms ├── CMakeLists.txt ├── binary_addition.cpp ├── boruvkas_minimum_spanning_tree.cpp ├── digit_separation.cpp ├── dijkstra_greedy.cpp ├── gale_shapley.cpp ├── huffman.cpp ├── jump_game.cpp ├── knapsack.cpp ├── kruskals_minimum_spanning_tree.cpp └── prims_minimum_spanning_tree.cpp ├── hashing ├── CMakeLists.txt ├── chaining.cpp ├── double_hash_hash_table.cpp ├── linear_probing_hash_table.cpp ├── md5.cpp ├── quadratic_probing_hash_table.cpp ├── sha1.cpp └── sha256.cpp ├── machine_learning ├── CMakeLists.txt ├── a_star_search.cpp ├── adaline_learning.cpp ├── iris.csv ├── k_nearest_neighbors.cpp ├── kohonen_som_topology.cpp ├── kohonen_som_trace.cpp ├── neural_network.cpp ├── ordinary_least_squares_regressor.cpp └── vector_ops.hpp ├── math ├── CMakeLists.txt ├── README.md ├── aliquot_sum.cpp ├── approximate_pi.cpp ├── area.cpp ├── armstrong_number.cpp ├── binary_exponent.cpp ├── binomial_calculate.cpp ├── check_amicable_pair.cpp ├── check_factorial.cpp ├── check_prime.cpp ├── complex_numbers.cpp ├── double_factorial.cpp ├── eratosthenes.cpp ├── eulers_totient_function.cpp ├── extended_euclid_algorithm.cpp ├── factorial.cpp ├── fast_power.cpp ├── fibonacci.cpp ├── fibonacci_fast.cpp ├── fibonacci_large.cpp ├── fibonacci_matrix_exponentiation.cpp ├── fibonacci_sum.cpp ├── finding_number_of_digits_in_a_number.cpp ├── gcd_iterative_euclidean.cpp ├── gcd_of_n_numbers.cpp ├── gcd_recursive_euclidean.cpp ├── integral_approximation.cpp ├── integral_approximation2.cpp ├── inv_sqrt.cpp ├── iterative_factorial.cpp ├── large_factorial.cpp ├── large_number.h ├── largest_power.cpp ├── lcm_sum.cpp ├── least_common_multiple.cpp ├── linear_recurrence_matrix.cpp ├── magic_number.cpp ├── miller_rabin.cpp ├── modular_division.cpp ├── modular_exponentiation.cpp ├── modular_inverse_fermat_little_theorem.cpp ├── modular_inverse_simple.cpp ├── n_bonacci.cpp ├── n_choose_r.cpp ├── ncr_modulo_p.cpp ├── number_of_positive_divisors.cpp ├── perimeter.cpp ├── power_for_huge_numbers.cpp ├── power_of_two.cpp ├── prime_factorization.cpp ├── prime_numbers.cpp ├── primes_up_to_billion.cpp ├── quadratic_equations_complex_numbers.cpp ├── realtime_stats.cpp ├── sieve_of_eratosthenes.cpp ├── sqrt_double.cpp ├── string_fibonacci.cpp ├── sum_of_binomial_coefficient.cpp ├── sum_of_digits.cpp ├── vector_cross_product.cpp └── volume.cpp ├── numerical_methods ├── CMakeLists.txt ├── babylonian_method.cpp ├── bisection_method.cpp ├── brent_method_extrema.cpp ├── composite_simpson_rule.cpp ├── durand_kerner_roots.cpp ├── false_position.cpp ├── fast_fourier_transform.cpp ├── gaussian_elimination.cpp ├── golden_search_extrema.cpp ├── gram_schmidt.cpp ├── inverse_fast_fourier_transform.cpp ├── lu_decompose.cpp ├── lu_decomposition.h ├── midpoint_integral_method.cpp ├── newton_raphson_method.cpp ├── ode_forward_euler.cpp ├── ode_midpoint_euler.cpp ├── ode_semi_implicit_euler.cpp ├── qr_decompose.h ├── qr_decomposition.cpp ├── qr_eigen_values.cpp ├── rungekutta.cpp └── successive_approximation.cpp ├── operations_on_datastructures ├── CMakeLists.txt ├── array_left_rotation.cpp ├── array_right_rotation.cpp ├── circular_linked_list.cpp ├── circular_queue_using_array.cpp ├── get_size_of_linked_list.cpp ├── inorder_successor_of_bst.cpp ├── intersection_of_two_arrays.cpp ├── reverse_a_linked_list_using_recusion.cpp ├── reverse_binary_tree.cpp ├── selectionsortlinkedlist.cpp ├── trie_multiple_search.cpp └── union_of_two_arrays.cpp ├── others ├── CMakeLists.txt ├── buzz_number.cpp ├── decimal_to_binary.cpp ├── decimal_to_hexadecimal.cpp ├── decimal_to_roman_numeral.cpp ├── easter.cpp ├── fast_integer_input.cpp ├── happy_number.cpp ├── iterative_tree_traversals.cpp ├── kadanes3.cpp ├── kelvin_to_celsius.cpp ├── lfu_cache.cpp ├── longest_substring_without_repeating_characters.cpp ├── lru_cache.cpp ├── lru_cache2.cpp ├── matrix_exponentiation.cpp ├── palindrome_of_number.cpp ├── paranthesis_matching.cpp ├── pascal_triangle.cpp ├── postfix_evaluation.cpp ├── primality_test.cpp ├── recursive_tree_traversal.cpp ├── smallest_circle.cpp ├── sparse_matrix.cpp ├── spiral_print.cpp ├── stairs_pattern.cpp ├── tower_of_hanoi.cpp └── vector_important_functions.cpp ├── physics ├── CMakeLists.txt └── ground_to_ground_projectile_motion.cpp ├── probability ├── CMakeLists.txt ├── addition_rule.cpp ├── bayes_theorem.cpp ├── binomial_dist.cpp ├── exponential_dist.cpp ├── geometric_dist.cpp ├── poisson_dist.cpp └── windowed_median.cpp ├── range_queries ├── CMakeLists.txt ├── fenwick_tree.cpp ├── heavy_light_decomposition.cpp ├── mo.cpp ├── persistent_seg_tree_lazy_prop.cpp ├── prefix_sum_array.cpp ├── segtree.cpp └── sparse_table_range_queries.cpp ├── scripts └── file_linter.py ├── search ├── CMakeLists.txt ├── binary_search.cpp ├── exponential_search.cpp ├── fibonacci_search.cpp ├── floyd_cycle_detection_algo.cpp ├── hash_search.cpp ├── interpolation_search.cpp ├── interpolation_search2.cpp ├── jump_search.cpp ├── linear_search.cpp ├── longest_increasing_subsequence_using_binary_search.cpp ├── median_search.cpp ├── median_search2.cpp ├── saddleback_search.cpp ├── sublist_search.cpp ├── ternary_search.cpp └── text_search.cpp ├── sorting ├── CMakeLists.txt ├── bead_sort.cpp ├── binary_insertion_sort.cpp ├── bitonic_sort.cpp ├── bogo_sort.cpp ├── bubble_sort.cpp ├── bucket_sort.cpp ├── cocktail_selection_sort.cpp ├── comb_sort.cpp ├── count_inversions.cpp ├── counting_sort.cpp ├── counting_sort_string.cpp ├── cycle_sort.cpp ├── dnf_sort.cpp ├── gnome_sort.cpp ├── heap_sort.cpp ├── insertion_sort.cpp ├── insertion_sort_recursive.cpp ├── library_sort.cpp ├── merge_insertion_sort.cpp ├── merge_sort.cpp ├── non_recursive_merge_sort.cpp ├── numeric_string_sort.cpp ├── odd_even_sort.cpp ├── pancake_sort.cpp ├── pigeonhole_sort.cpp ├── quick_sort.cpp ├── quick_sort_3.cpp ├── quick_sort_iterative.cpp ├── radix_sort.cpp ├── radix_sort2.cpp ├── random_pivot_quick_sort.cpp ├── recursive_bubble_sort.cpp ├── selection_sort_iterative.cpp ├── selection_sort_recursive.cpp ├── shell_sort.cpp ├── shell_sort2.cpp ├── slow_sort.cpp ├── stooge_sort.cpp ├── strand_sort.cpp ├── swap_sort.cpp ├── tim_sort.cpp ├── wave_sort.cpp └── wiggle_sort.cpp └── strings ├── CMakeLists.txt ├── boyer_moore.cpp ├── brute_force_string_searching.cpp ├── duval.cpp ├── horspool.cpp ├── knuth_morris_pratt.cpp ├── manacher_algorithm.cpp ├── rabin_karp.cpp └── z_function.cpp /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' 3 | WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-performance-move-const-arg,-performance-noexcept-move-constructor,-performance-unnecessary-value-param,-cppcoreguidelines-init-variables,-cppcoreguidelines-pro-*,-cppcoreguidelines-owning-memory,-clang-analyzer-cplusplus.Move' 4 | HeaderFilterRegex: '' 5 | AnalyzeTemporaryDtors: false 6 | FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }' 7 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @Panquesito7 @realstealthninja 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Create a report to help us improve. Report bugs found while using the project 3 | title: "[BUG]" 4 | labels: [bug] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Provide a general summary of the issue in the Title above 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: expectedbhv 15 | attributes: 16 | label: Expected behavior 17 | description: Tell us what should happen 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: actualbhv 22 | attributes: 23 | label: Actual behavior 24 | description: Tell us what happens instead 25 | validations: 26 | required: true 27 | - type: textarea 28 | id: steps 29 | attributes: 30 | label: Steps to reproduce 31 | description: | 32 | Provide a link to a live example, or an unambiguous set of steps to 33 | reproduce this bug. Include code to reproduce, if relevant 34 | placeholder: | 35 | 1. 36 | 2. 37 | 3. 38 | 4. 39 | validations: 40 | required: false 41 | - type: textarea 42 | id: context 43 | attributes: 44 | label: Context 45 | description: How has this bug affected you? What were you trying to accomplish? 46 | validations: 47 | required: true 48 | - type: textarea 49 | id: extrainformation 50 | attributes: 51 | label: Additional information 52 | description: Is there anything else we should know about this bug? 53 | validations: 54 | required: false 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Discord community 4 | url: https://the-algorithms.com/discord/ 5 | about: Have any questions or found any bugs? Please contact us via Discord 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest features, propose improvements, discuss new ideas. 3 | title: "[FEATURE]" 4 | labels: [enhancement] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: Provide a general summary of the issue in the Title above 9 | - type: textarea 10 | id: description 11 | attributes: 12 | label: Detailed description 13 | description: Provide a detailed description of the change or addition you are proposing 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: context 18 | attributes: 19 | label: Context 20 | description: | 21 | Why is this change important to you? How would you use it? 22 | How can it benefit other users? 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: possibleimpl 27 | attributes: 28 | label: Possible implementation 29 | description: Not obligatory, but suggest an idea for implementing addition or change 30 | validations: 31 | required: false 32 | - type: textarea 33 | id: extrainformation 34 | attributes: 35 | label: Additional information 36 | description: Is there anything else we should know about this feature? 37 | validations: 38 | required: false 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/other.yml: -------------------------------------------------------------------------------- 1 | name: Other issue 2 | description: Use this for any other issues. Do NOT create blank issues 3 | title: "[OTHER]" 4 | labels: ["awaiting triage"] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: What would you like to share? 10 | description: Provide a clear and concise explanation of your issue. 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: extrainfo 15 | attributes: 16 | label: Additional information 17 | description: Is there anything else we should know about this issue? 18 | validations: 19 | required: false 20 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | #### Description of Change 2 | 8 | 9 | #### Checklist 10 | 11 | 12 | - [ ] Added description of change 13 | - [ ] Added file name matches [File name guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md#New-File-Name-guidelines) 14 | - [ ] Added tests and example, test must pass 15 | - [ ] Added documentation so that the program is self-explanatory and educational - [Doxygen guidelines](https://www.doxygen.nl/manual/docblocks.html) 16 | - [ ] Relevant documentation/comments is changed or added 17 | - [ ] PR title follows semantic [commit guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md#Commit-Guidelines) 18 | - [ ] Search previous suggestions before making a new one, as yours may be a duplicate. 19 | - [ ] I acknowledge that all my contributions will be made under the project's license. 20 | 21 | Notes: 22 | -------------------------------------------------------------------------------- /.github/workflows/approved-label.yml: -------------------------------------------------------------------------------- 1 | on: pull_request_review 2 | name: Add "approved" label when approved 3 | jobs: 4 | add_label: 5 | name: Add "approved" label when approved 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Add "approved" label when approved 9 | uses: pullreminders/label-when-approved-action@master 10 | env: 11 | APPROVALS: "1" 12 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 13 | ADD_LABEL: "approved" 14 | REMOVE_LABEL: "" 15 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "Code Scanning - Action" 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | schedule: 9 | # ┌───────────── minute (0 - 59) 10 | # │ ┌───────────── hour (0 - 23) 11 | # │ │ ┌───────────── day of the month (1 - 31) 12 | # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) 13 | # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) 14 | # │ │ │ │ │ 15 | # │ │ │ │ │ 16 | # │ │ │ │ │ 17 | # * * * * * 18 | - cron: '30 1 * * 0' 19 | 20 | jobs: 21 | CodeQL-Build: 22 | # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest 23 | runs-on: ubuntu-latest 24 | 25 | permissions: 26 | # required for all workflows 27 | security-events: write 28 | 29 | # only required for workflows in private repositories 30 | actions: read 31 | contents: read 32 | 33 | steps: 34 | - name: Checkout repository 35 | uses: actions/checkout@v4 36 | 37 | # Initializes the CodeQL tools for scanning. 38 | - name: Initialize CodeQL 39 | uses: github/codeql-action/init@v2 40 | # Override language selection by uncommenting this and choosing your languages 41 | with: 42 | languages: cpp 43 | 44 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). 45 | # If this step fails, then you should remove it and run the build manually (see below). 46 | - name: Autobuild 47 | uses: github/codeql-action/autobuild@v2 48 | 49 | # ℹ️ Command-line programs to run using the OS shell. 50 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 51 | 52 | # ✏️ If the Autobuild fails above, remove it and uncomment the following 53 | # three lines and modify them (or add more) to build your code if your 54 | # project uses a compiled language 55 | 56 | #- run: | 57 | # make bootstrap 58 | # make release 59 | 60 | - name: Perform CodeQL Analysis 61 | uses: github/codeql-action/analyze@v2 62 | -------------------------------------------------------------------------------- /.github/workflows/directory_writer.yml: -------------------------------------------------------------------------------- 1 | name: Directory writer 2 | on: 3 | schedule: 4 | # ┌───────────── minute (0 - 59) 5 | # │ ┌───────────── hour (0 - 23) 6 | # │ │ ┌───────────── day of the month (1 - 31) 7 | # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) 8 | # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) 9 | # │ │ │ │ │ 10 | # │ │ │ │ │ 11 | # │ │ │ │ │ 12 | # * * * * * 13 | - cron: '0 0 * * *' 14 | workflow_dispatch: 15 | jobs: 16 | build: 17 | if: github.repository == 'TheAlgorithms/C-Plus-Plus' # We only need this to run in our repository. 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | - name: Build directory 24 | uses: TheAlgorithms/scripts/directory_md@main 25 | with: 26 | language: C-Plus-Plus 27 | working-directory: . 28 | filetypes: .cpp,.hpp,.h 29 | ignored-directories: doc/ 30 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Doxygen CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | build: 9 | runs-on: macos-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | with: 13 | submodules: true 14 | - name: Install requirements 15 | run: | 16 | brew install graphviz ninja doxygen 17 | - name: configure 18 | run: cmake -G Ninja -Duse_libclang=ON -DCMAKE_CXX_COMPILER=clang++ -B ./build -S . 19 | - name: build 20 | run: cmake --build build -t doc 21 | - name: gh-pages 22 | uses: actions/checkout@v4 23 | with: 24 | ref: "gh-pages" 25 | clean: false 26 | - name: Move & Commit files 27 | run: | 28 | git config --global user.name "$GITHUB_ACTOR" 29 | git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" 30 | git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY 31 | rm -rf d* && rm *.html && rm *.svg && rm *.map && rm *.md5 && rm *.png && rm *.js 32 | git add . 33 | cp -rp ./build/html/* . && rm -rf ./build && ls -lah 34 | git add . 35 | git commit -m "Documentation for $GITHUB_SHA" || true 36 | git push --force || true 37 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PRs' 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | jobs: 6 | stale: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/stale@v4 10 | with: 11 | stale-issue-message: 'This issue has been automatically marked as abandoned because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.' 12 | close-issue-message: 'Please ping one of the maintainers once you add more information and updates here. If this is not the case and you need some help, feel free to ask for help in our [Gitter](https://gitter.im/TheAlgorithms) channel or our [Discord server](https://the-algorithms.com/discord/). Thank you for your contributions!' 13 | stale-pr-message: 'This pull request has been automatically marked as abandoned because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.' 14 | close-pr-message: 'Please ping one of the maintainers once you commit the changes requested or make improvements on the code. If this is not the case and you need some help, feel free to ask for help in our [Gitter](https://gitter.im/TheAlgorithms) channel or our [Discord server](https://the-algorithms.com/discord/). Thank you for your contributions!' 15 | exempt-issue-labels: 'dont-close,approved' 16 | exempt-pr-labels: 'dont-close,approved' 17 | days-before-stale: 30 18 | days-before-close: 7 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Prerequisites 4 | *.d 5 | 6 | # Compiled Object files 7 | *.slo 8 | *.lo 9 | *.o 10 | *.obj 11 | 12 | # Precompiled Headers 13 | *.gch 14 | *.pch 15 | 16 | # Compiled Dynamic libraries 17 | *.so 18 | *.dylib 19 | *.dll 20 | 21 | # Fortran module files 22 | *.mod 23 | *.smod 24 | 25 | # Compiled Static libraries 26 | *.lai 27 | *.la 28 | *.a 29 | *.lib 30 | 31 | # Executables 32 | *.exe 33 | a.out 34 | *.out 35 | *.app 36 | 37 | # Cache 38 | .cache/ 39 | 40 | # Build 41 | build/ 42 | git_diff.txt 43 | -------------------------------------------------------------------------------- /.gitpod.dockerfile: -------------------------------------------------------------------------------- 1 | FROM gitpod/workspace-full-vnc 2 | 3 | RUN sudo apt-get update \ 4 | && sudo apt-get install -y \ 5 | doxygen \ 6 | graphviz \ 7 | ninja-build \ 8 | freeglut3 \ 9 | freeglut3-dev \ 10 | && pip install cpplint \ 11 | && sudo rm -rf /var/lib/apt/lists/* 12 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: 2 | file: .gitpod.dockerfile 3 | 4 | github: 5 | prebuilds: 6 | addBadge: true 7 | addComment: false 8 | addCheck: false 9 | master: true 10 | branches: true 11 | pullRequestsFromForks: true 12 | 13 | vscode: 14 | extensions: 15 | # - ms-vscode.cpptools 16 | - twxs.cmake 17 | - ms-vscode.cmake-tools 18 | - mhutchie.git-graph 19 | - notskm.clang-tidy 20 | - mitaki28.vscode-clang 21 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.clang_format_style": "{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }", 3 | "editor.formatOnSave": true, 4 | "editor.formatOnType": true, 5 | "editor.formatOnPaste": true, 6 | "files.associations": { 7 | "array": "cpp", 8 | "atomic": "cpp", 9 | "*.tcc": "cpp", 10 | "bitset": "cpp", 11 | "cctype": "cpp", 12 | "chrono": "cpp", 13 | "cinttypes": "cpp", 14 | "clocale": "cpp", 15 | "cmath": "cpp", 16 | "complex": "cpp", 17 | "cstdarg": "cpp", 18 | "cstddef": "cpp", 19 | "cstdint": "cpp", 20 | "cstdio": "cpp", 21 | "cstdlib": "cpp", 22 | "cstring": "cpp", 23 | "ctime": "cpp", 24 | "cwchar": "cpp", 25 | "cwctype": "cpp", 26 | "deque": "cpp", 27 | "list": "cpp", 28 | "unordered_map": "cpp", 29 | "unordered_set": "cpp", 30 | "vector": "cpp", 31 | "exception": "cpp", 32 | "algorithm": "cpp", 33 | "functional": "cpp", 34 | "iterator": "cpp", 35 | "map": "cpp", 36 | "memory": "cpp", 37 | "memory_resource": "cpp", 38 | "numeric": "cpp", 39 | "optional": "cpp", 40 | "random": "cpp", 41 | "ratio": "cpp", 42 | "set": "cpp", 43 | "string": "cpp", 44 | "string_view": "cpp", 45 | "system_error": "cpp", 46 | "tuple": "cpp", 47 | "type_traits": "cpp", 48 | "utility": "cpp", 49 | "fstream": "cpp", 50 | "initializer_list": "cpp", 51 | "iomanip": "cpp", 52 | "iosfwd": "cpp", 53 | "iostream": "cpp", 54 | "istream": "cpp", 55 | "limits": "cpp", 56 | "new": "cpp", 57 | "ostream": "cpp", 58 | "sstream": "cpp", 59 | "stdexcept": "cpp", 60 | "streambuf": "cpp", 61 | "typeinfo": "cpp", 62 | "valarray": "cpp", 63 | "bit": "cpp", 64 | "charconv": "cpp", 65 | "compare": "cpp", 66 | "concepts": "cpp", 67 | "format": "cpp", 68 | "forward_list": "cpp", 69 | "ios": "cpp", 70 | "locale": "cpp", 71 | "queue": "cpp", 72 | "stack": "cpp", 73 | "xfacet": "cpp", 74 | "xhash": "cpp", 75 | "xiosbase": "cpp", 76 | "xlocale": "cpp", 77 | "xlocbuf": "cpp", 78 | "xlocinfo": "cpp", 79 | "xlocmes": "cpp", 80 | "xlocmon": "cpp", 81 | "xlocnum": "cpp", 82 | "xloctime": "cpp", 83 | "xmemory": "cpp", 84 | "xstddef": "cpp", 85 | "xstring": "cpp", 86 | "xtr1common": "cpp", 87 | "xtree": "cpp", 88 | "xutility": "cpp", 89 | "climits": "cpp" 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | project(TheAlgorithms/C++ 3 | LANGUAGES CXX 4 | VERSION 1.0.0 5 | DESCRIPTION "Set of algorithms implemented in C++." 6 | ) 7 | 8 | # C++ standard 9 | set(CMAKE_CXX_STANDARD 17) 10 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 11 | 12 | # Additional warnings and errors 13 | if(MSVC) 14 | add_compile_definitions(_CRT_SECURE_NO_WARNINGS) 15 | add_compile_options(/W4 /permissive-) 16 | else() 17 | add_compile_options(-Wall -Wextra -Wno-register -Werror=vla) 18 | endif() 19 | 20 | option(USE_OPENMP "flag to use OpenMP for multithreading" ON) 21 | if(USE_OPENMP) 22 | find_package(OpenMP 3.0 COMPONENTS CXX) 23 | if (OpenMP_CXX_FOUND) 24 | message(STATUS "Building with OpenMP Multithreading.") 25 | else() 26 | message(STATUS "No OpenMP found, no multithreading.") 27 | endif() 28 | endif() 29 | 30 | add_subdirectory(math) 31 | add_subdirectory(others) 32 | add_subdirectory(search) 33 | add_subdirectory(ciphers) 34 | add_subdirectory(hashing) 35 | add_subdirectory(strings) 36 | add_subdirectory(sorting) 37 | add_subdirectory(geometry) 38 | add_subdirectory(graphics) 39 | add_subdirectory(probability) 40 | add_subdirectory(backtracking) 41 | add_subdirectory(bit_manipulation) 42 | add_subdirectory(dynamic_programming) 43 | add_subdirectory(greedy_algorithms) 44 | add_subdirectory(range_queries) 45 | add_subdirectory(operations_on_datastructures) 46 | add_subdirectory(data_structures) 47 | add_subdirectory(machine_learning) 48 | add_subdirectory(numerical_methods) 49 | add_subdirectory(graph) 50 | add_subdirectory(divide_and_conquer) 51 | add_subdirectory(games) 52 | add_subdirectory(cpu_scheduling_algorithms) 53 | add_subdirectory(physics) 54 | 55 | cmake_policy(SET CMP0054 NEW) 56 | cmake_policy(SET CMP0057 NEW) 57 | 58 | find_package(Doxygen OPTIONAL_COMPONENTS dot dia) 59 | if(DOXYGEN_FOUND) 60 | if(MSVC) 61 | set(DOXYGEN_CPP_CLI_SUPPORT YES) 62 | endif() 63 | 64 | if(Doxygen_dot_FOUND) 65 | set(DOXYGEN_HAVE_DOT YES) 66 | endif() 67 | 68 | if(OPENMP_FOUND) 69 | set(DOXYGEN_PREDEFINED "_OPENMP=1") 70 | endif() 71 | 72 | if(GLUT_FOUND) 73 | set(DOXYGEN_PREDEFINED ${DOXYGEN_PREDEFINED} "GLUT_FOUND=1") 74 | endif() 75 | 76 | doxygen_add_docs( 77 | doc 78 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 79 | COMMENT "Generate documentation" 80 | CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile 81 | ) 82 | endif() 83 | 84 | set(CPACK_PROJECT_NAME ${PROJECT_NAME}) 85 | set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) 86 | include(CPack) 87 | -------------------------------------------------------------------------------- /CodingGuidelines.md: -------------------------------------------------------------------------------- 1 | # Code style convention 2 | 3 | Please orient on this guide before you sent a pull request. 4 | 5 | --- 6 | 7 | ## User-interface 8 | 9 | Please write a simple user interface for your programs. Not a blinking cursor! 10 | What does the program do? 11 | What want the program an user informations? 12 | 13 | --- 14 | 15 | ## Code style conventions 16 | 17 | See [here](https://users.ece.cmu.edu/~eno/coding/CppCodingStandard.html) 18 | Don't push all code in one line! 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | Copyright (c) 2016-2024 TheAlgorithms and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /REVIEWER_CODE.md: -------------------------------------------------------------------------------- 1 | # Guidelines for reviewers and maintainers 2 | 3 | Following are some guidelines for contributors who are providing reviews to the pull-requests. 4 | 5 | 1. On any given pull-request, there only one reviewer should be active at a time. Once the reviewer is done, others may add short comments or any further reviews as needed. Again, one at a time. 6 | 2. Assigning reviewers should be avoided unless the pull-request is for a particular task the reviewer is more proficient in. 7 | 3. Any contributor who has had their code merged into the repo can provide with reviews as they have gone through the repo standards at least once before. The reviewer will be on a first-come-first serve basis. 8 | 4. Most repositories have a check-list in the description for pull-requests. Many times, the contributors are not following them and simply remove the checklist or checkthem without taking the time to review the checklist items. These contributors are almost always copying the code from somewhere. These should be pointed out politely and reviews should be blocked until the contributor updates the basic code structure per the checklist and the repo standards. 9 | 5. The reviewers should label every pull-request appropriately - including "invalid" as the case may be. 10 | 6. Some pull-requests have existing duplicate code or duplicate pull-requests or sometimes, a novice might create a new pull-request for every new commit. This is a daunting task but one of the responsibility of a reviewer. 11 | 7. Discourage creating branches on the repo but rather fork the repo to the respective userspace and contribute from that fork. 12 | 8. Some repos - C & C++ - have collaboration with GitPod wherein the code and the contribution can be executed and tested online with relative simplicity. It also contains tools necessary to perform debug and CI checks without installing any tools. Encourage contributors to utilize the feature. Reviewers can test the contributed algorithms online without worrying about forks and branches. 13 | 9. There should not be any hurry to merge pull-requests. Since the repos are educational, better to get the contributions right even if it takes a bit longer to review. Encourage patience and develop debugging skills of contributors. 14 | -------------------------------------------------------------------------------- /backtracking/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/backtracking") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /backtracking/minimax.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief returns which is the longest/shortest number 4 | * using [minimax](https://en.wikipedia.org/wiki/Minimax) algorithm 5 | * 6 | * @details 7 | * Minimax (sometimes MinMax, MM or saddle point) is a decision rule used in 8 | * artificial intelligence, decision theory, game theory, statistics, 9 | * and philosophy for minimizing the possible loss for a worst case (maximum 10 | * loss) scenario. When dealing with gains, it is referred to as "maximin"—to 11 | * maximize the minimum gain. Originally formulated for two-player zero-sum game 12 | * theory, covering both the cases where players take alternate moves and those 13 | * where they make simultaneous moves, it has also been extended to more complex 14 | * games and to general decision-making in the presence of uncertainty. 15 | * 16 | * @author [Gleison Batista](https://github.com/gleisonbs) 17 | * @author [David Leal](https://github.com/Panquesito7) 18 | */ 19 | #include /// for std::max, std::min 20 | #include /// for std::array 21 | #include /// for log2 22 | #include /// for IO operations 23 | 24 | /** 25 | * @namespace backtracking 26 | * @brief Backtracking algorithms 27 | */ 28 | namespace backtracking { 29 | /** 30 | * @brief Check which is the maximum/minimum number in the array 31 | * @param depth current depth in game tree 32 | * @param node_index current index in array 33 | * @param is_max if current index is the longest number 34 | * @param scores saved numbers in array 35 | * @param height maximum height for game tree 36 | * @returns the maximum or minimum number 37 | */ 38 | template 39 | int minimax(int depth, int node_index, bool is_max, 40 | const std::array &scores, double height) { 41 | if (depth == height) { 42 | return scores[node_index]; 43 | } 44 | 45 | int v1 = minimax(depth + 1, node_index * 2, !is_max, scores, height); 46 | int v2 = minimax(depth + 1, node_index * 2 + 1, !is_max, scores, height); 47 | 48 | return is_max ? std::max(v1, v2) : std::min(v1, v2); 49 | } 50 | } // namespace backtracking 51 | 52 | /** 53 | * @brief Main function 54 | * @returns 0 on exit 55 | */ 56 | int main() { 57 | std::array scores = {90, 23, 6, 33, 21, 65, 123, 34423}; 58 | double height = log2(scores.size()); 59 | 60 | std::cout << "Optimal value: " 61 | << backtracking::minimax(0, 0, true, scores, height) << std::endl; 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /bit_manipulation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/bit_manipulation") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /bit_manipulation/power_of_2.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief [Find whether a given number is power of 2] 4 | * (https://www.geeksforgeeks.org/program-to-find-whether-a-given-number-is-power-of-2/) 5 | * implementation 6 | * 7 | * @details 8 | * We are given a positive integer number. We need to check whether the number 9 | * is power of 2 or not. 10 | * 11 | * A binary number consists of two digits. They are 0 & 1. Digit 1 is known as 12 | * set bit in computer terms. 13 | * Worst Case Time Complexity: O(1) 14 | * Space complexity: O(1) 15 | * @author [Prafful Gupta](https://github.com/EcstaticPG-25811) 16 | */ 17 | 18 | #include /// for assert 19 | #include 20 | #include /// for IO operations 21 | 22 | /** 23 | * @namespace bit_manipulation 24 | * @brief Bit manipulation algorithms 25 | */ 26 | namespace bit_manipulation { 27 | /** 28 | * @brief The main function implements check for power of 2 29 | * @param n is the number who will be checked 30 | * @returns either true or false 31 | */ 32 | bool isPowerOfTwo(std ::int64_t n) { // int64_t is preferred over int so that 33 | // no Overflow can be there. 34 | 35 | return n > 0 && !(n & n - 1); // If we subtract a power of 2 numbers by 1 36 | // then all unset bits after the only set bit become set; and the set bit 37 | // becomes unset. 38 | 39 | // If a number n is a power of 2 then bitwise and of n-1 and n will be zero. 40 | // The expression n&(n-1) will not work when n is 0. 41 | // To handle this case also, our expression will become n& (!n&(n-1)) 42 | } 43 | } // namespace bit_manipulation 44 | 45 | /** 46 | * @brief Self-test implementations 47 | * @returns void 48 | */ 49 | static void test() { 50 | // n = 4 return true 51 | assert(bit_manipulation::isPowerOfTwo(4) == true); 52 | // n = 6 return false 53 | assert(bit_manipulation::isPowerOfTwo(6) == false); 54 | // n = 13 return false 55 | assert(bit_manipulation::isPowerOfTwo(13) == false); 56 | // n = 64 return true 57 | assert(bit_manipulation::isPowerOfTwo(64) == true); 58 | // n = 15 return false 59 | assert(bit_manipulation::isPowerOfTwo(15) == false); 60 | // n = 32 return true 61 | assert(bit_manipulation::isPowerOfTwo(32) == true); 62 | // n = 97 return false 63 | assert(bit_manipulation::isPowerOfTwo(97) == false); 64 | // n = 1024 return true 65 | assert(bit_manipulation::isPowerOfTwo(1024) == true); 66 | std::cout << "All test cases successfully passed!" << std::endl; 67 | } 68 | /** 69 | * @brief Main function 70 | * @returns 0 on exit 71 | */ 72 | int main() { 73 | test(); // run self-test implementations 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /ciphers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/ciphers") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /cpu_scheduling_algorithms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. The RELATIVE flag makes it easier to extract an executable's name 3 | # automatically. 4 | 5 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 6 | foreach( testsourcefile ${APP_SOURCES} ) 7 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) # File type. Example: `.cpp` 8 | add_executable( ${testname} ${testsourcefile} ) 9 | 10 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 11 | if(OpenMP_CXX_FOUND) 12 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 13 | endif() 14 | install(TARGETS ${testname} DESTINATION "bin/cpu_scheduling_algorithms") # Folder name. Do NOT include `<>` 15 | 16 | endforeach( testsourcefile ${APP_SOURCES} ) 17 | -------------------------------------------------------------------------------- /data_structures/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/data_structures") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | 20 | add_subdirectory(cll) 21 | -------------------------------------------------------------------------------- /data_structures/circular_queue_using_linked_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct node { 4 | int data; 5 | struct node* next; 6 | }; 7 | class Queue { 8 | node* front = nullptr; 9 | node* rear = nullptr; 10 | 11 | Queue(const Queue&) = delete; 12 | Queue& operator=(const Queue&) = delete; 13 | 14 | public: 15 | Queue() = default; 16 | ~Queue() { 17 | while (front) { 18 | dequeue(); 19 | } 20 | } 21 | 22 | private: 23 | void createNode(int val) { 24 | auto* nn = new node; 25 | nn->data = val; 26 | nn->next = nullptr; 27 | front = nn; 28 | rear = nn; 29 | } 30 | 31 | public: 32 | void enqueue(int val) { 33 | if (front == nullptr || rear == nullptr) { 34 | createNode(val); 35 | } else { 36 | node* nn = new node; 37 | nn->data = val; 38 | rear->next = nn; 39 | nn->next = front; 40 | rear = nn; 41 | } 42 | } 43 | void dequeue() { 44 | if (front == nullptr) { 45 | return; 46 | } 47 | const node* const n = front; 48 | if (front == rear) { 49 | front = nullptr; 50 | rear = nullptr; 51 | } else { 52 | front = front->next; 53 | rear->next = front; 54 | } 55 | delete n; 56 | } 57 | void traverse() { 58 | if (front == nullptr) { 59 | return; 60 | } 61 | const node* ptr = front; 62 | do { 63 | std::cout << ptr->data << ' '; 64 | ptr = ptr->next; 65 | } while (ptr != front); 66 | std::cout << '\n'; 67 | } 68 | }; 69 | int main(void) { 70 | Queue q; 71 | q.enqueue(10); 72 | q.enqueue(20); 73 | q.enqueue(30); 74 | q.enqueue(40); 75 | q.enqueue(50); 76 | q.enqueue(60); 77 | q.enqueue(70); 78 | q.traverse(); 79 | q.dequeue(); 80 | q.traverse(); 81 | return 0; 82 | } -------------------------------------------------------------------------------- /data_structures/cll/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable( cll 2 | cll.cpp 3 | main_cll.cpp 4 | ) 5 | install(TARGETS cll DESTINATION "bin/data_structures") 6 | -------------------------------------------------------------------------------- /data_structures/cll/cll.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple data structure CLL (Cicular Linear Linked List) 3 | * */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifndef CLL_H 10 | #define CLL_H 11 | /*The data structure is a linear linked list of integers */ 12 | struct node { 13 | int data; 14 | node* next; 15 | }; 16 | 17 | class cll { 18 | public: 19 | cll(); /* Construct without parameter */ 20 | ~cll(); 21 | void display(); /* Show the list */ 22 | 23 | /****************************************************** 24 | * Useful method for list 25 | *******************************************************/ 26 | void insert_front(int new_data); /* Insert a new value at head */ 27 | void insert_tail(int new_data); /* Insert a new value at tail */ 28 | int get_size(); /* Get total element in list */ 29 | bool find_item(int item_to_find); /* Find an item in list */ 30 | 31 | /****************************************************** 32 | * Overloading method for list 33 | *******************************************************/ 34 | int operator*(); /* Returns the info contained in head */ 35 | /* Overload the pre-increment operator. 36 | The iterator is advanced to the next node. */ 37 | void operator++(); 38 | 39 | protected: 40 | node* head; 41 | int total; /* Total element in a list */ 42 | }; 43 | #endif 44 | -------------------------------------------------------------------------------- /data_structures/cll/main_cll.cpp: -------------------------------------------------------------------------------- 1 | #include "cll.h" 2 | using namespace std; 3 | 4 | int main() { 5 | /* Test CLL */ 6 | cout << "----------- Test construct -----------" << endl; 7 | cll list1; 8 | list1.display(); 9 | cout << "----------- Test insert front -----------" << endl; 10 | list1.insert_front(5); 11 | cout << "After insert 5 at front: " << endl; 12 | list1.display(); 13 | cout << "After insert 10 3 7 at front: " << endl; 14 | list1.insert_front(10); 15 | list1.insert_front(3); 16 | list1.insert_front(7); 17 | list1.display(); 18 | cout << "----------- Test insert tail -----------" << endl; 19 | cout << "After insert 18 19 20 at tail: " << endl; 20 | list1.insert_tail(18); 21 | list1.insert_tail(19); 22 | list1.insert_tail(20); 23 | list1.display(); 24 | cout << "----------- Test find item -----------" << endl; 25 | if (list1.find_item(10)) 26 | cout << "PASS" << endl; 27 | else 28 | cout << "FAIL" << endl; 29 | if (!list1.find_item(30)) 30 | cout << "PASS" << endl; 31 | else 32 | cout << "FAIL" << endl; 33 | cout << "----------- Test * operator -----------" << endl; 34 | int value = *list1; 35 | cout << "Value at *list1: " << value << endl; 36 | cout << "----------- Test ++ operator -----------" << endl; 37 | list1.display(); 38 | ++list1; 39 | cout << "After ++list1: " << endl; 40 | list1.display(); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /data_structures/node.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Provides Node class and related utilities 4 | **/ 5 | #ifndef DATA_STRUCTURES_NODE_HPP_ 6 | #define DATA_STRUCTURES_NODE_HPP_ 7 | 8 | #include /// for std::cout 9 | #include /// for std::shared_ptr 10 | #include /// for std::vector 11 | 12 | /** Definition of the node as a linked-list 13 | * \tparam ValueType type of data nodes of the linked list should contain 14 | */ 15 | template 16 | struct Node { 17 | using value_type = ValueType; 18 | ValueType data = {}; 19 | std::shared_ptr> next = {}; 20 | }; 21 | 22 | template 23 | void traverse(const Node* const inNode, const Action& action) { 24 | if (inNode) { 25 | action(*inNode); 26 | traverse(inNode->next.get(), action); 27 | } 28 | } 29 | 30 | template 31 | void display_all(const Node* const inNode) { 32 | traverse(inNode, 33 | [](const Node& curNode) { std::cout << curNode.data << " "; }); 34 | } 35 | 36 | template 37 | std::vector push_all_to_vector( 38 | const Node* const inNode, const std::size_t expected_size = 0) { 39 | std::vector res; 40 | res.reserve(expected_size); 41 | traverse(inNode, 42 | [&res](const Node& curNode) { res.push_back(curNode.data); }); 43 | return res; 44 | } 45 | 46 | #endif // DATA_STRUCTURES_NODE_HPP_ 47 | -------------------------------------------------------------------------------- /data_structures/queue_using_array2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int queue[10]; 5 | int front = 0; 6 | int rear = 0; 7 | 8 | void Enque(int x) { 9 | if (rear == 10) { 10 | cout << "\nOverflow"; 11 | } else { 12 | queue[rear++] = x; 13 | } 14 | } 15 | 16 | void Deque() { 17 | if (front == rear) { 18 | cout << "\nUnderflow"; 19 | } 20 | 21 | else { 22 | cout << "\n" << queue[front++] << " deleted"; 23 | for (int i = front; i < rear; i++) { 24 | queue[i - front] = queue[i]; 25 | } 26 | rear = rear - front; 27 | front = 0; 28 | } 29 | } 30 | 31 | void show() { 32 | for (int i = front; i < rear; i++) { 33 | cout << queue[i] << "\t"; 34 | } 35 | } 36 | 37 | int main() { 38 | int ch, x; 39 | do { 40 | cout << "\n1. Enque"; 41 | cout << "\n2. Deque"; 42 | cout << "\n3. Print"; 43 | cout << "\nEnter Your Choice : "; 44 | cin >> ch; 45 | if (ch == 1) { 46 | cout << "\nInsert : "; 47 | cin >> x; 48 | Enque(x); 49 | } else if (ch == 2) { 50 | Deque(); 51 | } else if (ch == 3) { 52 | show(); 53 | } 54 | } while (ch != 0); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /data_structures/queue_using_linked_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct node { 5 | int val; 6 | node *next; 7 | }; 8 | 9 | node *front, *rear; 10 | 11 | void Enque(int x) { 12 | if (rear == NULL) { 13 | node *n = new node; 14 | n->val = x; 15 | n->next = NULL; 16 | rear = n; 17 | front = n; 18 | } 19 | 20 | else { 21 | node *n = new node; 22 | n->val = x; 23 | n->next = NULL; 24 | rear->next = n; 25 | rear = n; 26 | } 27 | } 28 | 29 | void Deque() { 30 | if (rear == NULL && front == NULL) { 31 | cout << "\nUnderflow"; 32 | } else { 33 | node *t = front; 34 | cout << "\n" << t->val << " deleted"; 35 | front = front->next; 36 | delete t; 37 | if (front == NULL) 38 | rear = NULL; 39 | } 40 | } 41 | 42 | void show() { 43 | node *t = front; 44 | while (t != NULL) { 45 | cout << t->val << "\t"; 46 | t = t->next; 47 | } 48 | } 49 | 50 | int main() { 51 | int ch, x; 52 | do { 53 | cout << "\n1. Enque"; 54 | cout << "\n2. Deque"; 55 | cout << "\n3. Print"; 56 | cout << "\nEnter Your Choice : "; 57 | cin >> ch; 58 | if (ch == 1) { 59 | cout << "\nInsert : "; 60 | cin >> x; 61 | Enque(x); 62 | } else if (ch == 2) { 63 | Deque(); 64 | } else if (ch == 3) { 65 | show(); 66 | } 67 | } while (ch != 0); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /data_structures/queue_using_linkedlist.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Write a program to implement Queue using linkedlist. 3 | */ 4 | #include 5 | 6 | struct linkedlist { 7 | int data; 8 | linkedlist *next; 9 | }; 10 | class stack_linkedList { 11 | public: 12 | linkedlist *front; 13 | linkedlist *rear; 14 | 15 | stack_linkedList() { front = rear = NULL; } 16 | void enqueue(int); 17 | int dequeue(); 18 | void display(); 19 | }; 20 | void stack_linkedList::enqueue(int ele) { 21 | linkedlist *temp = new linkedlist(); 22 | temp->data = ele; 23 | temp->next = NULL; 24 | 25 | if (front == NULL) 26 | front = rear = temp; 27 | else { 28 | rear->next = temp; 29 | rear = temp; 30 | } 31 | } 32 | int stack_linkedList::dequeue() { 33 | linkedlist *temp; 34 | int ele; 35 | if (front == NULL) 36 | std::cout << "\nStack is empty"; 37 | else { 38 | temp = front; 39 | ele = temp->data; 40 | if (front == rear) // if length of queue is 1; 41 | rear = rear->next; 42 | front = front->next; 43 | delete (temp); 44 | } 45 | return ele; 46 | } 47 | void stack_linkedList::display() { 48 | if (front == NULL) 49 | std::cout << "\nStack is empty"; 50 | 51 | else { 52 | linkedlist *temp; 53 | temp = front; 54 | while (temp != NULL) { 55 | std::cout << temp->data << " "; 56 | temp = temp->next; 57 | } 58 | } 59 | } 60 | 61 | int main() { 62 | int op, data; 63 | stack_linkedList ob; 64 | std::cout << "\n1. enqueue(Insertion) "; 65 | std::cout << "\n2. dequeue(Deletion)"; 66 | std::cout << "\n3. Display"; 67 | std::cout << "\n4. Exit"; 68 | 69 | while (1) { 70 | std::cout << "\nEnter your choice "; 71 | std::cin >> op; 72 | if (op == 1) { 73 | std::cout << "Enter data "; 74 | std::cin >> data; 75 | ob.enqueue(data); 76 | } else if (op == 2) 77 | data = ob.dequeue(); 78 | else if (op == 3) 79 | ob.display(); 80 | else if (op == 4) 81 | exit(0); 82 | else 83 | std::cout << "\nWrong choice "; 84 | } 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /data_structures/stack.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @author danghai 4 | * @author [Piotr Idzik](https://github.com/vil02) 5 | * @brief This class specifies the basic operation on a stack as a linked list 6 | **/ 7 | #ifndef DATA_STRUCTURES_STACK_HPP_ 8 | #define DATA_STRUCTURES_STACK_HPP_ 9 | 10 | #include /// for std::invalid_argument 11 | 12 | #include "node.hpp" /// for Node 13 | 14 | /** Definition of the stack class 15 | * \tparam value_type type of data nodes of the linked list in the stack should 16 | * contain 17 | */ 18 | template 19 | class stack { 20 | public: 21 | using value_type = ValueType; 22 | 23 | /** Show stack */ 24 | void display() const { 25 | std::cout << "Top --> "; 26 | display_all(this->stackTop.get()); 27 | std::cout << '\n'; 28 | std::cout << "Size of stack: " << size << std::endl; 29 | } 30 | 31 | std::vector toVector() const { 32 | return push_all_to_vector(this->stackTop.get(), this->size); 33 | } 34 | 35 | private: 36 | void ensureNotEmpty() const { 37 | if (isEmptyStack()) { 38 | throw std::invalid_argument("Stack is empty."); 39 | } 40 | } 41 | 42 | public: 43 | /** Determine whether the stack is empty */ 44 | bool isEmptyStack() const { return (stackTop == nullptr); } 45 | 46 | /** Add new item to the stack */ 47 | void push(const value_type& item) { 48 | auto newNode = std::make_shared>(); 49 | newNode->data = item; 50 | newNode->next = stackTop; 51 | stackTop = newNode; 52 | size++; 53 | } 54 | 55 | /** Return the top element of the stack */ 56 | value_type top() const { 57 | ensureNotEmpty(); 58 | return stackTop->data; 59 | } 60 | 61 | /** Remove the top element of the stack */ 62 | void pop() { 63 | ensureNotEmpty(); 64 | stackTop = stackTop->next; 65 | size--; 66 | } 67 | 68 | /** Clear stack */ 69 | void clear() { 70 | stackTop = nullptr; 71 | size = 0; 72 | } 73 | 74 | private: 75 | std::shared_ptr> stackTop = 76 | {}; /**< Pointer to the stack */ 77 | std::size_t size = 0; ///< size of stack 78 | }; 79 | 80 | #endif // DATA_STRUCTURES_STACK_HPP_ 81 | -------------------------------------------------------------------------------- /data_structures/stack_using_linked_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct node { 4 | int val; 5 | node *next; 6 | }; 7 | 8 | node *top_var; 9 | 10 | void push(int x) { 11 | node *n = new node; 12 | n->val = x; 13 | n->next = top_var; 14 | top_var = n; 15 | } 16 | 17 | void pop() { 18 | if (top_var == nullptr) { 19 | std::cout << "\nUnderflow"; 20 | } else { 21 | node *t = top_var; 22 | std::cout << "\n" << t->val << " deleted"; 23 | top_var = top_var->next; 24 | delete t; 25 | } 26 | } 27 | 28 | void show() { 29 | node *t = top_var; 30 | while (t != nullptr) { 31 | std::cout << t->val << "\n"; 32 | t = t->next; 33 | } 34 | } 35 | 36 | int main() { 37 | int ch = 0, x = 0; 38 | do { 39 | std::cout << "\n0. Exit or Ctrl+C"; 40 | std::cout << "\n1. Push"; 41 | std::cout << "\n2. Pop"; 42 | std::cout << "\n3. Print"; 43 | std::cout << "\nEnter Your Choice: "; 44 | std::cin >> ch; 45 | switch (ch) { 46 | case 0: 47 | break; 48 | case 1: 49 | std::cout << "\nInsert : "; 50 | std::cin >> x; 51 | push(x); 52 | break; 53 | case 2: 54 | pop(); 55 | break; 56 | case 3: 57 | show(); 58 | break; 59 | default: 60 | std::cout << "Invalid option!\n"; 61 | break; 62 | } 63 | } while (ch != 0); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /data_structures/student.txt: -------------------------------------------------------------------------------- 1 | 3.4 Tom 2 | 3.2 Kathy 3 | 2.5 Hoang 4 | 3.4 Tom 5 | 3.8 Randy 6 | 3.9 Kingston 7 | 3.8 Mickey 8 | 3.6 Peter 9 | 3.5 Donald 10 | 3.8 Cindy 11 | 3.7 Dome 12 | 3.9 Andy 13 | 3.8 Hai 14 | 3.9 Minnie 15 | 2.7 Gilda 16 | 3.9 Vinay 17 | 3.4 Hiral 18 | -------------------------------------------------------------------------------- /data_structures/test_queue.cpp: -------------------------------------------------------------------------------- 1 | #include /// for assert 2 | #include /// for std::cout 3 | 4 | #include "./queue.hpp" 5 | 6 | template 7 | void testConstructedQueueIsEmpty() { 8 | const queue curQueue; 9 | assert(curQueue.isEmptyQueue()); 10 | } 11 | 12 | void testEnQueue() { 13 | queue curQueue; 14 | curQueue.enQueue(10); 15 | assert(curQueue.toVector() == std::vector({10})); 16 | curQueue.enQueue(20); 17 | assert(curQueue.toVector() == std::vector({10, 20})); 18 | curQueue.enQueue(30); 19 | curQueue.enQueue(40); 20 | assert(curQueue.toVector() == std::vector({10, 20, 30, 40})); 21 | } 22 | 23 | void testDeQueue() { 24 | queue curQueue; 25 | curQueue.enQueue(10); 26 | curQueue.enQueue(20); 27 | curQueue.enQueue(30); 28 | 29 | curQueue.deQueue(); 30 | assert(curQueue.toVector() == std::vector({20, 30})); 31 | 32 | curQueue.deQueue(); 33 | assert(curQueue.toVector() == std::vector({30})); 34 | 35 | curQueue.deQueue(); 36 | assert(curQueue.isEmptyQueue()); 37 | } 38 | 39 | void testFront() { 40 | queue curQueue; 41 | curQueue.enQueue(10); 42 | assert(curQueue.front() == 10); 43 | curQueue.enQueue(20); 44 | assert(curQueue.front() == 10); 45 | } 46 | 47 | void testQueueAfterClearIsEmpty() { 48 | queue curQueue; 49 | curQueue.enQueue(10); 50 | curQueue.enQueue(20); 51 | curQueue.enQueue(30); 52 | curQueue.clear(); 53 | assert(curQueue.isEmptyQueue()); 54 | } 55 | 56 | void testFrontThrowsAnInvalidArgumentWhenQueueEmpty() { 57 | const queue curQueue; 58 | bool wasException = false; 59 | try { 60 | curQueue.front(); 61 | } catch (const std::invalid_argument&) { 62 | wasException = true; 63 | } 64 | assert(wasException); 65 | } 66 | 67 | void testDeQueueThrowsAnInvalidArgumentWhenQueueEmpty() { 68 | queue curQueue; 69 | bool wasException = false; 70 | try { 71 | curQueue.deQueue(); 72 | } catch (const std::invalid_argument&) { 73 | wasException = true; 74 | } 75 | assert(wasException); 76 | } 77 | 78 | int main() { 79 | testConstructedQueueIsEmpty(); 80 | testConstructedQueueIsEmpty(); 81 | testConstructedQueueIsEmpty>(); 82 | 83 | testEnQueue(); 84 | testDeQueue(); 85 | 86 | testQueueAfterClearIsEmpty(); 87 | 88 | testFrontThrowsAnInvalidArgumentWhenQueueEmpty(); 89 | testDeQueueThrowsAnInvalidArgumentWhenQueueEmpty(); 90 | 91 | std::cout << "All tests pass!\n"; 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /data_structures/test_stack_students.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program reads a data file consisting of students' GPAs 3 | * followed by their names. The program then prints the highest 4 | * GPA and the names of the students with the highest GPA. 5 | * It uses stack to store the names of the students 6 | * Run: 7 | * make all 8 | * ./main student.txt 9 | ************************************************************ 10 | * */ 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "./stack.hpp" 19 | 20 | int main(int argc, char* argv[]) { 21 | double GPA = NAN; 22 | double highestGPA = NAN; 23 | std::string name; 24 | 25 | assert(argc == 2); 26 | std::ifstream infile; 27 | stack stk; 28 | 29 | infile.open(argv[1]); 30 | std::cout << std::fixed << std::showpoint; 31 | std::cout << std::setprecision(2); 32 | infile >> GPA >> name; 33 | highestGPA = GPA; 34 | 35 | while (infile) { 36 | if (GPA > highestGPA) { 37 | stk.clear(); 38 | stk.push(name); 39 | highestGPA = GPA; 40 | } else if (GPA == highestGPA) { 41 | stk.push(name); 42 | } 43 | infile >> GPA >> name; 44 | } 45 | std::cout << "Highest GPA: " << highestGPA << std::endl; 46 | std::cout << "Students the highest GPA are: " << std::endl; 47 | while (!stk.isEmptyStack()) { 48 | std::cout << stk.top() << std::endl; 49 | stk.pop(); 50 | } 51 | std::cout << std::endl; 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /divide_and_conquer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/divide_and_conquer") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /doc/assets/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /doc/assets/project_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheAlgorithms/C-Plus-Plus/93a700c7e947c8704df387564ea4780e6c031967/doc/assets/project_logo.png -------------------------------------------------------------------------------- /dynamic_programming/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/dynamic_programming") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /dynamic_programming/coin_change.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // Function to find the Minimum number of coins required to get Sum S 7 | int findMinCoins(int arr[], int n, int N) { 8 | // dp[i] = no of coins required to get a total of i 9 | std::vector dp(N + 1); 10 | 11 | // 0 coins are needed for 0 sum 12 | 13 | dp[0] = 0; 14 | 15 | for (int i = 1; i <= N; i++) { 16 | // initialize minimum number of coins needed to infinity 17 | dp[i] = INT_MAX; 18 | int res = INT_MAX; 19 | 20 | // do for each coin 21 | for (int c = 0; c < n; c++) { 22 | if (i - arr[c] >= 23 | 0) // check if coins doesn't become negative by including it 24 | res = dp[i - arr[c]]; 25 | 26 | // if total can be reached by including current coin c, 27 | // update minimum number of coins needed dp[i] 28 | if (res != INT_MAX) 29 | dp[i] = min(dp[i], res + 1); 30 | } 31 | } 32 | 33 | // The Minimum No of Coins Required for N = dp[N] 34 | return dp[N]; 35 | } 36 | 37 | int main() { 38 | // No of Coins We Have 39 | int arr[] = {1, 2, 3, 4}; 40 | int n = sizeof(arr) / sizeof(arr[0]); 41 | 42 | // Total Change Required 43 | int N = 15; 44 | 45 | cout << "Minimum Number of Coins Required " << findMinCoins(arr, n, N) 46 | << "\n"; 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /dynamic_programming/edit_distance.cpp: -------------------------------------------------------------------------------- 1 | /* Given two strings str1 & str2 2 | * and below operations that can 3 | * be performed on str1. Find 4 | * minimum number of edits 5 | * (operations) required to convert 6 | * 'str1' into 'str2'/ 7 | * a. Insert 8 | * b. Remove 9 | * c. Replace 10 | * All of the above operations are 11 | * of equal cost 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | int min(int x, int y, int z) { return min(min(x, y), z); } 20 | 21 | /* A Naive recursive C++ program to find 22 | * minimum number of operations to convert 23 | * str1 to str2. 24 | * O(3^m) 25 | */ 26 | int editDist(string str1, string str2, int m, int n) { 27 | if (m == 0) 28 | return n; 29 | if (n == 0) 30 | return m; 31 | 32 | // If last characters are same then continue 33 | // for the rest of them. 34 | if (str1[m - 1] == str2[n - 1]) 35 | return editDist(str1, str2, m - 1, n - 1); 36 | 37 | // If last not same, then 3 possibilities 38 | // a.Insert b.Remove c. Replace 39 | // Get min of three and continue for rest. 40 | return 1 + min(editDist(str1, str2, m, n - 1), 41 | editDist(str1, str2, m - 1, n), 42 | editDist(str1, str2, m - 1, n - 1)); 43 | } 44 | 45 | /* A DP based program 46 | * O(m x n) 47 | */ 48 | int editDistDP(string str1, string str2, int m, int n) { 49 | // Create Table for SubProblems 50 | std::vector > dp(m + 1, std::vector(n + 1)); 51 | 52 | // Fill d[][] in bottom up manner 53 | for (int i = 0; i <= m; i++) { 54 | for (int j = 0; j <= n; j++) { 55 | // If str1 empty. Then add all of str2 56 | if (i == 0) 57 | dp[i][j] = j; 58 | 59 | // If str2 empty. Then add all of str1 60 | else if (j == 0) 61 | dp[i][j] = i; 62 | 63 | // If character same. Recur for remaining 64 | else if (str1[i - 1] == str2[j - 1]) 65 | dp[i][j] = dp[i - 1][j - 1]; 66 | 67 | else 68 | dp[i][j] = 1 + min(dp[i][j - 1], // Insert 69 | dp[i - 1][j], // Remove 70 | dp[i - 1][j - 1] // Replace 71 | ); 72 | } 73 | } 74 | 75 | return dp[m][n]; 76 | } 77 | 78 | int main() { 79 | string str1 = "sunday"; 80 | string str2 = "saturday"; 81 | 82 | cout << editDist(str1, str2, str1.length(), str2.length()) << endl; 83 | cout << editDistDP(str1, str2, str1.length(), str2.length()) << endl; 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /dynamic_programming/egg_dropping_puzzle.cpp: -------------------------------------------------------------------------------- 1 | /* Function to get minimun number of trials needed 2 | * in worst case with n eggs and k floors 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | int eggDrop(int n, int k) { 12 | std::vector > eggFloor(n + 1, std::vector(k + 1)); 13 | 14 | int result; 15 | 16 | for (int i = 1; i <= n; i++) { 17 | eggFloor[i][1] = 1; // n eggs..1 Floor 18 | eggFloor[i][0] = 0; // n eggs..0 Floor 19 | } 20 | 21 | // Only one egg available 22 | for (int j = 1; j <= k; j++) { 23 | eggFloor[1][j] = j; 24 | } 25 | 26 | for (int i = 2; i <= n; i++) { 27 | for (int j = 2; j <= k; j++) { 28 | eggFloor[i][j] = INT_MAX; 29 | for (int x = 1; x <= j; x++) { 30 | // 1+max(eggBreak[one less egg, lower floors], 31 | // eggDoesntBreak[same # of eggs, upper floors]); 32 | result = 1 + max(eggFloor[i - 1][x - 1], eggFloor[i][j - x]); 33 | if (result < eggFloor[i][j]) 34 | eggFloor[i][j] = result; 35 | } 36 | } 37 | } 38 | 39 | return eggFloor[n][k]; 40 | } 41 | 42 | int main() { 43 | int n, k; 44 | cout << "Enter number of eggs and floors: "; 45 | cin >> n >> k; 46 | cout << "Minimum number of trials in worst case: " << eggDrop(n, k) << endl; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /dynamic_programming/fibonacci_bottom_up.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int fib(int n) { 4 | int res[3]; 5 | res[0] = 0; 6 | res[1] = 1; 7 | for (int i = 2; i <= n; i++) { 8 | res[2] = res[1] + res[0]; 9 | res[0] = res[1]; 10 | res[1] = res[2]; 11 | } 12 | return res[1]; 13 | } 14 | int main(int argc, char const *argv[]) { 15 | int n; 16 | cout << "Enter n: "; 17 | cin >> n; 18 | cout << "Fibonacci number is "; 19 | cout << fib(n) << endl; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /dynamic_programming/longest_common_subsequence.cpp: -------------------------------------------------------------------------------- 1 | // Longest common subsequence - Dynamic Programming 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | void Print(int trace[20][20], int m, int n, string a) { 7 | if (m == 0 || n == 0) { 8 | return; 9 | } 10 | if (trace[m][n] == 1) { 11 | Print(trace, m - 1, n - 1, a); 12 | cout << a[m - 1]; 13 | } else if (trace[m][n] == 2) { 14 | Print(trace, m - 1, n, a); 15 | } else if (trace[m][n] == 3) { 16 | Print(trace, m, n - 1, a); 17 | } 18 | } 19 | 20 | int lcs(string a, string b) { 21 | int m = a.length(), n = b.length(); 22 | std::vector > res(m + 1, std::vector(n + 1)); 23 | int trace[20][20]; 24 | 25 | // fills up the arrays with zeros. 26 | for (int i = 0; i < m + 1; i++) { 27 | for (int j = 0; j < n + 1; j++) { 28 | res[i][j] = 0; 29 | trace[i][j] = 0; 30 | } 31 | } 32 | 33 | for (int i = 0; i < m + 1; ++i) { 34 | for (int j = 0; j < n + 1; ++j) { 35 | if (i == 0 || j == 0) { 36 | res[i][j] = 0; 37 | trace[i][j] = 0; 38 | } 39 | 40 | else if (a[i - 1] == b[j - 1]) { 41 | res[i][j] = 1 + res[i - 1][j - 1]; 42 | trace[i][j] = 1; // 1 means trace the matrix in upper left 43 | // diagonal direction. 44 | } else { 45 | if (res[i - 1][j] > res[i][j - 1]) { 46 | res[i][j] = res[i - 1][j]; 47 | trace[i][j] = 48 | 2; // 2 means trace the matrix in upwards direction. 49 | } else { 50 | res[i][j] = res[i][j - 1]; 51 | trace[i][j] = 52 | 3; // means trace the matrix in left direction. 53 | } 54 | } 55 | } 56 | } 57 | Print(trace, m, n, a); 58 | return res[m][n]; 59 | } 60 | 61 | int main() { 62 | string a, b; 63 | cin >> a >> b; 64 | cout << lcs(a, b); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /dynamic_programming/longest_increasing_subsequence_nlogn.cpp: -------------------------------------------------------------------------------- 1 | // Program to calculate length of longest increasing subsequence in an array 2 | // in O(n log n) 3 | // tested on : https://cses.fi/problemset/task/1145/ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | int LIS(const std::vector& arr, int n) { 11 | set active; // The current built LIS. 12 | active.insert(arr[0]); 13 | // Loop through every element. 14 | for (int i = 1; i < n; ++i) { 15 | auto get = active.lower_bound(arr[i]); 16 | if (get == active.end()) { 17 | active.insert(arr[i]); 18 | } // current element is the greatest so LIS increases by 1. 19 | else { 20 | int val = *get; // we find the position where arr[i] will be in the 21 | // LIS. If it is in the LIS already we do nothing 22 | if (val > arr[i]) { 23 | // else we remove the bigger element and add a smaller element 24 | // (which is arr[i]) and continue; 25 | active.erase(get); 26 | active.insert(arr[i]); 27 | } 28 | } 29 | } 30 | return active.size(); // size of the LIS. 31 | } 32 | int main(int argc, char const* argv[]) { 33 | int n; 34 | cout << "Enter size of array: "; 35 | cin >> n; 36 | std::vector a(n); 37 | cout << "Enter array elements: "; 38 | for (int i = 0; i < n; ++i) { 39 | cin >> a[i]; 40 | } 41 | cout << LIS(a, n) << endl; 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /dynamic_programming/matrix_chain_multiplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #define MAX 10 6 | 7 | // dp table to store the solution for already computed sub problems 8 | int dp[MAX][MAX]; 9 | 10 | // Function to find the most efficient way to multiply the given sequence of 11 | // matrices 12 | int MatrixChainMultiplication(int dim[], int i, int j) { 13 | // base case: one matrix 14 | if (j <= i + 1) 15 | return 0; 16 | 17 | // stores minimum number of scalar multiplications (i.e., cost) 18 | // needed to compute the matrix M[i+1]...M[j] = M[i..j] 19 | int min = INT_MAX; 20 | 21 | // if dp[i][j] is not calculated (calculate it!!) 22 | 23 | if (dp[i][j] == 0) { 24 | // take the minimum over each possible position at which the 25 | // sequence of matrices can be split 26 | 27 | for (int k = i + 1; k <= j - 1; k++) { 28 | // recur for M[i+1]..M[k] to get a i x k matrix 29 | int cost = MatrixChainMultiplication(dim, i, k); 30 | 31 | // recur for M[k+1]..M[j] to get a k x j matrix 32 | cost += MatrixChainMultiplication(dim, k, j); 33 | 34 | // cost to multiply two (i x k) and (k x j) matrix 35 | cost += dim[i] * dim[k] * dim[j]; 36 | 37 | if (cost < min) 38 | min = cost; // store the minimum cost 39 | } 40 | dp[i][j] = min; 41 | } 42 | 43 | // return min cost to multiply M[j+1]..M[j] 44 | return dp[i][j]; 45 | } 46 | 47 | // main function 48 | int main() { 49 | // Matrix i has Dimensions dim[i-1] & dim[i] for i=1..n 50 | // input is 10 x 30 matrix, 30 x 5 matrix, 5 x 60 matrix 51 | int dim[] = {10, 30, 5, 60}; 52 | int n = sizeof(dim) / sizeof(dim[0]); 53 | 54 | // Function Calling: MatrixChainMultiplications(dimensions_array, starting, 55 | // ending); 56 | 57 | cout << "Minimum cost is " << MatrixChainMultiplication(dim, 0, n - 1) 58 | << "\n"; 59 | 60 | return 0; 61 | } -------------------------------------------------------------------------------- /dynamic_programming/tree_height.cpp: -------------------------------------------------------------------------------- 1 | // C++ Program to find height of the tree using bottom-up dynamic programming. 2 | 3 | /* 4 | * Given a rooted tree with node 1. 5 | * Task is to find the height of the tree. 6 | * Example: - 7 | * 4 8 | * 1 2 9 | * 1 3 10 | * 2 4 11 | * which can be represented as 12 | * 1 13 | * / \ 14 | * 2 3 15 | * | 16 | * 4 17 | * 18 | * Height of the tree : - 2 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | // global declarations 25 | // no of nodes max limit. 26 | const int MAX = 1e5; 27 | // adjacency list 28 | std::vector adj[MAX]; 29 | std::vector visited; 30 | std::vector dp; 31 | 32 | void depth_first_search(int u) { 33 | visited[u] = true; 34 | int child_height = 1; 35 | for (int v : adj[u]) { 36 | if (!visited[v]) { 37 | depth_first_search(v); 38 | 39 | // select maximum sub-tree height from all children. 40 | child_height = std::max(child_height, dp[v] + 1); 41 | } 42 | } 43 | // assigned the max child height to current visited node. 44 | dp[u] = child_height; 45 | } 46 | 47 | int main() { 48 | // number of nodes 49 | int number_of_nodes; 50 | std::cout << "Enter number of nodes of the tree : " << std::endl; 51 | std::cin >> number_of_nodes; 52 | 53 | // u, v denotes an undirected edge of tree. 54 | int u, v; 55 | // Tree contains exactly n-1 edges where n denotes the number of nodes. 56 | std::cout << "Enter edges of the tree : " << std::endl; 57 | for (int i = 0; i < number_of_nodes - 1; i++) { 58 | std::cin >> u >> v; 59 | // undirected tree u -> v and v -> u. 60 | adj[u].push_back(v); 61 | adj[v].push_back(u); 62 | } 63 | // initialize all nodes as unvisited. 64 | visited.assign(number_of_nodes + 1, false); 65 | // initialize depth of all nodes to 0. 66 | dp.assign(number_of_nodes + 1, 0); 67 | // function call which will initialize the height of all nodes. 68 | depth_first_search(1); 69 | std::cout << "Height of the Tree : " << dp[1] << std::endl; 70 | } 71 | -------------------------------------------------------------------------------- /games/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. The RELATIVE flag makes it easier to extract an executable's name 3 | # automatically. 4 | 5 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 6 | foreach( testsourcefile ${APP_SOURCES} ) 7 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) # File type. Example: `.cpp` 8 | add_executable( ${testname} ${testsourcefile} ) 9 | 10 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 11 | if(OpenMP_CXX_FOUND) 12 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 13 | endif() 14 | install(TARGETS ${testname} DESTINATION "bin/games") # Folder name. Do NOT include `<>` 15 | 16 | endforeach( testsourcefile ${APP_SOURCES} ) 17 | -------------------------------------------------------------------------------- /geometry/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/geometry") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /graph/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | #with full pathname.RELATIVE may makes it easier to extract an executable name 3 | #automatically. 4 | file(GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) 5 | #file(GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES 13 | LINKER_LANGUAGE CXX 14 | ) 15 | if(OpenMP_CXX_FOUND) 16 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 17 | endif() 18 | install(TARGETS ${testname} DESTINATION "bin/graph") 19 | 20 | endforeach( testsourcefile ${APP_SOURCES} ) 21 | -------------------------------------------------------------------------------- /graph/bridge_finding_with_tarjan_algorithm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright : 2020 , MIT 3 | * Author : Amit Kumar (offamitkumar) 4 | * Last Modified Date: May 24, 2020 5 | * 6 | */ 7 | #include // for min & max 8 | #include // for cout 9 | #include // for std::vector 10 | 11 | class Solution { 12 | std::vector> graph; 13 | std::vector in_time, out_time; 14 | int timer = 0; 15 | std::vector> bridge; 16 | std::vector visited; 17 | void dfs(int current_node, int parent) { 18 | visited.at(current_node) = true; 19 | in_time[current_node] = out_time[current_node] = timer++; 20 | for (auto& itr : graph[current_node]) { 21 | if (itr == parent) { 22 | continue; 23 | } 24 | if (!visited[itr]) { 25 | dfs(itr, current_node); 26 | if (out_time[itr] > in_time[current_node]) { 27 | bridge.push_back({itr, current_node}); 28 | } 29 | } 30 | out_time[current_node] = 31 | std::min(out_time[current_node], out_time[itr]); 32 | } 33 | } 34 | 35 | public: 36 | std::vector> search_bridges( 37 | int n, const std::vector>& connections) { 38 | timer = 0; 39 | graph.resize(n); 40 | in_time.assign(n, 0); 41 | visited.assign(n, false); 42 | out_time.assign(n, 0); 43 | for (auto& itr : connections) { 44 | graph.at(itr[0]).push_back(itr[1]); 45 | graph.at(itr[1]).push_back(itr[0]); 46 | } 47 | dfs(0, -1); 48 | return bridge; 49 | } 50 | }; 51 | 52 | /** 53 | * Main function 54 | */ 55 | int main() { 56 | Solution s1; 57 | int number_of_node = 5; 58 | std::vector> node; 59 | node.push_back({0, 1}); 60 | node.push_back({1, 3}); 61 | node.push_back({1, 2}); 62 | node.push_back({2, 4}); 63 | /* 64 | * 0 <--> 1 <---> 2 65 | * ^ ^ 66 | * | | 67 | * | | 68 | * \/ \/ 69 | * 3 4 70 | * 71 | * In this graph there are 4 bridges [0,2] , [2,4] , [3,5] , [1,2] 72 | * 73 | * I assumed that the graph is bi-directional and connected. 74 | * 75 | */ 76 | std::vector> bridges = 77 | s1.search_bridges(number_of_node, node); 78 | std::cout << bridges.size() << " bridges found!\n"; 79 | for (auto& itr : bridges) { 80 | std::cout << itr[0] << " --> " << itr[1] << '\n'; 81 | } 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /graph/kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | //#include 6 | // using namespace boost::multiprecision; 7 | const int mx = 1e6 + 5; 8 | using ll = int64_t; 9 | 10 | std::array parent; 11 | ll node, edge; 12 | std::vector>> edges; 13 | void initial() { 14 | for (int i = 0; i < node + edge; ++i) { 15 | parent[i] = i; 16 | } 17 | } 18 | 19 | int root(int i) { 20 | while (parent[i] != i) { 21 | parent[i] = parent[parent[i]]; 22 | i = parent[i]; 23 | } 24 | return i; 25 | } 26 | 27 | void join(int x, int y) { 28 | int root_x = root(x); // Disjoint set union by rank 29 | int root_y = root(y); 30 | parent[root_x] = root_y; 31 | } 32 | 33 | ll kruskal() { 34 | ll mincost = 0; 35 | for (int i = 0; i < edge; ++i) { 36 | ll x = edges[i].second.first; 37 | ll y = edges[i].second.second; 38 | if (root(x) != root(y)) { 39 | mincost += edges[i].first; 40 | join(x, y); 41 | } 42 | } 43 | return mincost; 44 | } 45 | 46 | int main() { 47 | while (true) { 48 | int from = 0, to = 0, cost = 0, totalcost = 0; 49 | std::cin >> node >> edge; // Enter the nodes and edges 50 | if (node == 0 && edge == 0) { 51 | break; // Enter 0 0 to break out 52 | } 53 | initial(); // Initialise the parent array 54 | for (int i = 0; i < edge; ++i) { 55 | std::cin >> from >> to >> cost; 56 | edges.emplace_back(make_pair(cost, std::make_pair(from, to))); 57 | totalcost += cost; 58 | } 59 | sort(edges.begin(), edges.end()); 60 | std::cout << kruskal() << std::endl; 61 | edges.clear(); 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /graph/prim.cpp: -------------------------------------------------------------------------------- 1 | // C++ program to implement Prim's Algorithm 2 | #include 3 | #include 4 | #include 5 | 6 | using PII = std::pair; 7 | 8 | int prim(int x, const std::vector > &graph) { 9 | // priority queue to maintain edges with respect to weights 10 | std::priority_queue, std::greater > Q; 11 | std::vector marked(graph.size(), false); 12 | int minimum_cost = 0; 13 | 14 | Q.push(std::make_pair(0, x)); 15 | while (!Q.empty()) { 16 | // Select the edge with minimum weight 17 | PII p = Q.top(); 18 | Q.pop(); 19 | x = p.second; 20 | // Checking for cycle 21 | if (marked[x] == true) { 22 | continue; 23 | } 24 | minimum_cost += p.first; 25 | marked[x] = true; 26 | for (const PII &neighbor : graph[x]) { 27 | int y = neighbor.second; 28 | if (marked[y] == false) { 29 | Q.push(neighbor); 30 | } 31 | } 32 | } 33 | return minimum_cost; 34 | } 35 | 36 | int main() { 37 | int nodes = 0, edges = 0; 38 | std::cin >> nodes >> edges; // number of nodes & edges in graph 39 | if (nodes == 0 || edges == 0) { 40 | return 0; 41 | } 42 | 43 | std::vector > graph(nodes); 44 | 45 | // Edges with their nodes & weight 46 | for (int i = 0; i < edges; ++i) { 47 | int x = 0, y = 0, weight = 0; 48 | std::cin >> x >> y >> weight; 49 | graph[x].push_back(std::make_pair(weight, y)); 50 | graph[y].push_back(std::make_pair(weight, x)); 51 | } 52 | 53 | // Selecting 1 as the starting node 54 | int minimum_cost = prim(1, graph); 55 | std::cout << minimum_cost << std::endl; 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /graph/topological_sort_by_kahns_algo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | std::vector topoSortKahn(int N, const std::vector > &adj); 8 | 9 | int main() { 10 | int nodes = 0, edges = 0; 11 | std::cin >> edges >> nodes; 12 | if (edges == 0 || nodes == 0) { 13 | return 0; 14 | } 15 | int u = 0, v = 0; 16 | 17 | std::vector > graph(nodes); 18 | // create graph 19 | // example 20 | // 6 6 21 | // 5 0 5 2 2 3 4 0 4 1 1 3 22 | 23 | for (int i = 0; i < edges; i++) { 24 | std::cin >> u >> v; 25 | graph[u].push_back(v); 26 | } 27 | 28 | std::vector topo = topoSortKahn(nodes, graph); 29 | // topologically sorted nodes 30 | for (int i = 0; i < nodes; i++) { 31 | std::cout << topo[i] << " "; 32 | } 33 | } 34 | 35 | std::vector topoSortKahn(int V, 36 | const std::vector > &adj) { 37 | std::vector vis(V + 1, false); 38 | std::vector deg(V + 1, 0); 39 | for (int i = 0; i < V; i++) { 40 | for (int j : adj[i]) { 41 | deg[j]++; 42 | } 43 | } 44 | std::queue q; 45 | for (int i = 0; i < V; i++) { 46 | if (deg[i] == 0) { 47 | q.push(i); 48 | vis[i] = true; 49 | } 50 | } 51 | std::vector arr(V + 1, 0); 52 | int count = 0; 53 | while (!q.empty()) { 54 | int cur = q.front(); 55 | q.pop(); 56 | arr[count++] = cur; 57 | for (int i : adj[cur]) { 58 | if (!vis[i]) { 59 | deg[i]--; 60 | if (deg[i] == 0) { 61 | q.push(i); 62 | vis[i] = true; 63 | } 64 | } 65 | } 66 | } 67 | return arr; 68 | } 69 | -------------------------------------------------------------------------------- /greedy_algorithms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/greedy_algorithms") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /greedy_algorithms/knapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct Item { 5 | int weight; 6 | int profit; 7 | }; 8 | 9 | float profitPerUnit(Item x) { return (float)x.profit / (float)x.weight; } 10 | 11 | int partition(Item arr[], int low, int high) { 12 | Item pivot = arr[high]; // pivot 13 | int i = (low - 1); // Index of smaller element 14 | 15 | for (int j = low; j < high; j++) { 16 | // If current element is smaller than or 17 | // equal to pivot 18 | if (profitPerUnit(arr[j]) <= profitPerUnit(pivot)) { 19 | i++; // increment index of smaller element 20 | Item temp = arr[i]; 21 | arr[i] = arr[j]; 22 | arr[j] = temp; 23 | } 24 | } 25 | Item temp = arr[i + 1]; 26 | arr[i + 1] = arr[high]; 27 | arr[high] = temp; 28 | return (i + 1); 29 | } 30 | 31 | void quickSort(Item arr[], int low, int high) { 32 | if (low < high) { 33 | int p = partition(arr, low, high); 34 | 35 | quickSort(arr, low, p - 1); 36 | quickSort(arr, p + 1, high); 37 | } 38 | } 39 | 40 | int main() { 41 | cout << "\nEnter the capacity of the knapsack : "; 42 | float capacity; 43 | cin >> capacity; 44 | cout << "\n Enter the number of Items : "; 45 | int n; 46 | cin >> n; 47 | Item *itemArray = new Item[n]; 48 | for (int i = 0; i < n; i++) { 49 | cout << "\nEnter the weight and profit of item " << i + 1 << " : "; 50 | cin >> itemArray[i].weight; 51 | cin >> itemArray[i].profit; 52 | } 53 | 54 | quickSort(itemArray, 0, n - 1); 55 | 56 | // show(itemArray, n); 57 | 58 | float maxProfit = 0; 59 | int i = n; 60 | while (capacity > 0 && --i >= 0) { 61 | if (capacity >= itemArray[i].weight) { 62 | maxProfit += itemArray[i].profit; 63 | capacity -= itemArray[i].weight; 64 | cout << "\n\t" << itemArray[i].weight << "\t" 65 | << itemArray[i].profit; 66 | } else { 67 | maxProfit += profitPerUnit(itemArray[i]) * capacity; 68 | cout << "\n\t" << capacity << "\t" 69 | << profitPerUnit(itemArray[i]) * capacity; 70 | capacity = 0; 71 | break; 72 | } 73 | } 74 | 75 | cout << "\nMax Profit : " << maxProfit; 76 | delete[] itemArray; 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /greedy_algorithms/prims_minimum_spanning_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define V 4 5 | #define INFINITY 99999 6 | 7 | int graph[V][V] = {{0, 5, 1, 2}, {5, 0, 3, 3}, {1, 3, 0, 4}, {2, 3, 4, 0}}; 8 | 9 | struct mst { 10 | bool visited; 11 | int key; 12 | int near; 13 | }; 14 | 15 | mst MST_Array[V]; 16 | 17 | void initilize() { 18 | for (int i = 0; i < V; i++) { 19 | MST_Array[i].visited = false; 20 | MST_Array[i].key = INFINITY; // considering INFINITY as inifinity 21 | MST_Array[i].near = i; 22 | } 23 | 24 | MST_Array[0].key = 0; 25 | } 26 | 27 | void updateNear() { 28 | for (int v = 0; v < V; v++) { 29 | int min = INFINITY; 30 | int minIndex = 0; 31 | for (int i = 0; i < V; i++) { 32 | if (MST_Array[i].key < min && MST_Array[i].visited == false && 33 | MST_Array[i].key != INFINITY) { 34 | min = MST_Array[i].key; 35 | minIndex = i; 36 | } 37 | } 38 | 39 | MST_Array[minIndex].visited = true; 40 | 41 | for (int i = 0; i < V; i++) { 42 | if (graph[minIndex][i] != 0 && graph[minIndex][i] < INFINITY) { 43 | if (graph[minIndex][i] < MST_Array[i].key) { 44 | MST_Array[i].key = graph[minIndex][i]; 45 | MST_Array[i].near = minIndex; 46 | } 47 | } 48 | } 49 | } 50 | } 51 | 52 | void show() { 53 | for (int i = 0; i < V; i++) { 54 | cout << i << " - " << MST_Array[i].near << "\t" 55 | << graph[i][MST_Array[i].near] << "\n"; 56 | } 57 | } 58 | 59 | int main() { 60 | initilize(); 61 | updateNear(); 62 | show(); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /hashing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/hash") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /machine_learning/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/machine_learning") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /math/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/math") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /math/README.md: -------------------------------------------------------------------------------- 1 | # Prime factorization # {#section} 2 | Prime Factorization is a very important and useful technique to factorize any number into its prime factors. It has various applications in the field of number theory. 3 | 4 | The method of prime factorization involves two function calls. 5 | First: Calculating all the prime number up till a certain range using the standard 6 | Sieve of Eratosthenes. 7 | 8 | Second: Using the prime numbers to reduce the the given number and thus find all its prime factors. 9 | 10 | The complexity of the solution involves approx. O(n logn) in calculating sieve of eratosthenes 11 | O(log n) in calculating the prime factors of the number. So in total approx. O(n logn). 12 | 13 | **Requirements: For compile you need the compiler flag for C++ 11** 14 | -------------------------------------------------------------------------------- /math/aliquot_sum.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Program to return the [Aliquot 4 | * Sum](https://en.wikipedia.org/wiki/Aliquot_sum) of a number 5 | * 6 | * @details 7 | * The Aliquot sum \f$s(n)\f$ of a non-negative integer n is the sum of all 8 | * proper divisors of n, that is, all the divisors of n, other than itself. 9 | * 10 | * Formula: 11 | * 12 | * \f[ 13 | * s(n) = \sum_{d|n, d\neq n}d. 14 | * \f] 15 | * 16 | * For example; 17 | * \f$s(18) = 1 + 2 + 3 + 6 + 9 = 21 \f$ 18 | * 19 | * @author [SpiderMath](https://github.com/SpiderMath) 20 | */ 21 | 22 | #include /// for assert 23 | #include 24 | #include /// for IO operations 25 | 26 | /** 27 | * @brief Mathematical algorithms 28 | * @namespace math 29 | */ 30 | namespace math { 31 | 32 | /** 33 | * @brief to return the aliquot sum of a number 34 | * @param num The input number 35 | */ 36 | uint64_t aliquot_sum(const uint64_t num) { 37 | if (num == 0 || num == 1) { 38 | return 0; // The aliquot sum for 0 and 1 is 0 39 | } 40 | 41 | uint64_t sum = 0; 42 | 43 | for (uint64_t i = 1; i <= num / 2; i++) { 44 | if (num % i == 0) { 45 | sum += i; 46 | } 47 | } 48 | 49 | return sum; 50 | } 51 | } // namespace math 52 | 53 | /** 54 | * @brief Self-test implementations 55 | * @returns void 56 | */ 57 | static void test() { 58 | // Aliquot sum of 10 is 1 + 2 + 5 = 8 59 | assert(math::aliquot_sum(10) == 8); 60 | // Aliquot sum of 15 is 1 + 3 + 5 = 9 61 | assert(math::aliquot_sum(15) == 9); 62 | // Aliquot sum of 1 is 0 63 | assert(math::aliquot_sum(1) == 0); 64 | // Aliquot sum of 97 is 1 (the aliquot sum of a prime number is 1) 65 | assert(math::aliquot_sum(97) == 1); 66 | 67 | std::cout << "All the tests have successfully passed!\n"; 68 | } 69 | 70 | /** 71 | * @brief Main function 72 | * @returns 0 on exit 73 | */ 74 | int main() { 75 | test(); // run the self-test implementations 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /math/approximate_pi.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief 4 | * Implementation to calculate an estimate of the [number π 5 | * (Pi)](https://en.wikipedia.org/wiki/File:Pi_30K.gif). 6 | * 7 | * @details 8 | * We take a random point P with coordinates (x, y) such that 0 ≤ x ≤ 1 and 0 ≤ 9 | * y ≤ 1. If x² + y² ≤ 1, then the point is inside the quarter disk of radius 1, 10 | * else the point is outside. We know that the probability of the point being 11 | * inside the quarter disk is equal to π/4 double approx(vector &pts) 12 | * which will use the points pts (drawn at random) to return an estimate of the 13 | * number π 14 | * @note This implementation is better than naive recursive or iterative 15 | * approach. 16 | * 17 | * @author [Qannaf AL-SAHMI](https://github.com/Qannaf) 18 | */ 19 | 20 | #include /// for assert 21 | #include /// for std::rand 22 | #include /// for IO operations 23 | #include /// for std::vector 24 | 25 | /** 26 | * @namespace math 27 | * @brief Mathematical algorithms 28 | */ 29 | namespace math { 30 | 31 | /** 32 | * @brief structure of points containing two numbers, x and y, such that 0 ≤ x ≤ 33 | * 1 and 0 ≤ y ≤ 1. 34 | */ 35 | using Point = struct { 36 | double x; 37 | double y; 38 | }; 39 | 40 | /** 41 | * @brief This function uses the points in a given vector 'pts' (drawn at 42 | * random) to return an approximation of the number π. 43 | * @param pts Each item of pts contains a point. A point is represented by the 44 | * point structure (coded above). 45 | * @return an estimate of the number π. 46 | */ 47 | double approximate_pi(const std::vector &pts) { 48 | double count = 0; // Points in circle 49 | for (Point p : pts) { 50 | if ((p.x * p.x) + (p.y * p.y) <= 1) { 51 | count++; 52 | } 53 | } 54 | return 4.0 * count / static_cast(pts.size()); 55 | } 56 | } // namespace math 57 | 58 | /** 59 | * @brief Self-test implementations 60 | * @returns void 61 | */ 62 | static void tests() { 63 | std::vector rands; 64 | for (std::size_t i = 0; i < 100000; i++) { 65 | math::Point p; 66 | p.x = rand() / static_cast(RAND_MAX); // 0 <= x <= 1 67 | p.y = rand() / static_cast(RAND_MAX); // 0 <= y <= 1 68 | rands.push_back(p); 69 | } 70 | assert(math::approximate_pi(rands) > 3.135); 71 | assert(math::approximate_pi(rands) < 3.145); 72 | 73 | std::cout << "All tests have successfully passed!" << std::endl; 74 | } 75 | 76 | /** 77 | * @brief Main function 78 | * @returns 0 on exit 79 | */ 80 | int main() { 81 | tests(); // run self-test implementations 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /math/binary_exponent.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief C++ Program to find Binary Exponent Iteratively and Recursively. 4 | * 5 | * Calculate \f$a^b\f$ in \f$O(\log(b))\f$ by converting \f$b\f$ to a 6 | * binary number. Binary exponentiation is also known as exponentiation by 7 | * squaring. 8 | * @note This is a far better approach compared to naive method which 9 | * provide \f$O(b)\f$ operations. 10 | * 11 | * Example: 12 | *
10 in base 2 is 1010. 13 | * \f{eqnarray*}{ 14 | * 2^{10_d} &=& 2^{1010_b} = 2^8 * 2^2\\ 15 | * 2^1 &=& 2\\ 16 | * 2^2 &=& (2^1)^2 = 2^2 = 4\\ 17 | * 2^4 &=& (2^2)^2 = 4^2 = 16\\ 18 | * 2^8 &=& (2^4)^2 = 16^2 = 256\\ 19 | * \f} 20 | * Hence to calculate 2^10 we only need to multiply \f$2^8\f$ and \f$2^2\f$ 21 | * skipping \f$2^1\f$ and \f$2^4\f$. 22 | */ 23 | 24 | #include 25 | 26 | /// Recursive function to calculate exponent in \f$O(\log(n))\f$ using binary 27 | /// exponent. 28 | int binExpo(int a, int b) { 29 | if (b == 0) { 30 | return 1; 31 | } 32 | int res = binExpo(a, b / 2); 33 | if (b % 2) { 34 | return res * res * a; 35 | } else { 36 | return res * res; 37 | } 38 | } 39 | 40 | /// Iterative function to calculate exponent in \f$O(\log(n))\f$ using binary 41 | /// exponent. 42 | int binExpo_alt(int a, int b) { 43 | int res = 1; 44 | while (b > 0) { 45 | if (b % 2) { 46 | res = res * a; 47 | } 48 | a = a * a; 49 | b /= 2; 50 | } 51 | return res; 52 | } 53 | 54 | /// Main function 55 | int main() { 56 | int a, b; 57 | /// Give two numbers a, b 58 | std::cin >> a >> b; 59 | if (a == 0 && b == 0) { 60 | std::cout << "Math error" << std::endl; 61 | } else if (b < 0) { 62 | std::cout << "Exponent must be positive !!" << std::endl; 63 | } else { 64 | int resRecurse = binExpo(a, b); 65 | /// int resIterate = binExpo_alt(a, b); 66 | 67 | /// Result of a^b (where '^' denotes exponentiation) 68 | std::cout << resRecurse << std::endl; 69 | /// std::cout << resIterate << std::endl; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /math/check_factorial.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief A simple program to check if the given number is a 4 | * [factorial](https://en.wikipedia.org/wiki/Factorial) of some number or not. 5 | * 6 | * @details A factorial number is the sum of k! where any value of k is a 7 | * positive integer. https://www.mathsisfun.com/numbers/factorial.html 8 | * 9 | * @author [Divyajyoti Ukirde](https://github.com/divyajyotiuk) 10 | * @author [ewd00010](https://github.com/ewd00010) 11 | */ 12 | #include /// for assert 13 | #include 14 | #include /// for cout 15 | 16 | /** 17 | * @namespace 18 | * @brief Mathematical algorithms 19 | */ 20 | namespace math { 21 | /** 22 | * @brief Function to check if the given number is factorial of some number or 23 | * not. 24 | * @param n number to be checked. 25 | * @return true if number is a factorial returns true 26 | * @return false if number is not a factorial 27 | */ 28 | bool is_factorial(uint64_t n) { 29 | if (n <= 0) { // factorial numbers are only ever positive Integers 30 | return false; 31 | } 32 | 33 | /*! 34 | * this loop is basically a reverse factorial calculation, where instead 35 | * of multiplying we are dividing. We start at i = 2 since i = 1 has 36 | * no impact division wise 37 | */ 38 | int i = 2; 39 | while (n % i == 0) { 40 | n = n / i; 41 | i++; 42 | } 43 | 44 | /*! 45 | * if n was the sum of a factorial then it should be divided until it 46 | * becomes 1 47 | */ 48 | return (n == 1); 49 | } 50 | } // namespace math 51 | 52 | /** 53 | * @brief Self-test implementations 54 | * @returns void 55 | */ 56 | static void tests() { 57 | assert(math::is_factorial(50) == false); 58 | assert(math::is_factorial(720) == true); 59 | assert(math::is_factorial(0) == false); 60 | assert(math::is_factorial(1) == true); 61 | assert(math::is_factorial(479001600) == true); 62 | assert(math::is_factorial(-24) == false); 63 | 64 | std::cout << "All tests have successfully passed!" << std::endl; 65 | } 66 | 67 | /** 68 | * @brief Main function 69 | * @returns 0 on exit 70 | */ 71 | int main() { 72 | tests(); // run self-test implementations 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /math/double_factorial.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Compute [double 4 | * factorial](https://en.wikipedia.org/wiki/Double_factorial): \f$n!!\f$ 5 | * 6 | * Double factorial of a non-negative integer `n`, is defined as the product of 7 | * all the integers from 1 to n that have the same parity (odd or even) as n. 8 | *
It is also called as semifactorial of a number and is denoted by 9 | * \f$n!!\f$ 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | /** Compute double factorial using iterative method 17 | */ 18 | uint64_t double_factorial_iterative(uint64_t n) { 19 | uint64_t res = 1; 20 | for (uint64_t i = n;; i -= 2) { 21 | if (i == 0 || i == 1) 22 | return res; 23 | res *= i; 24 | } 25 | return res; 26 | } 27 | 28 | /** Compute double factorial using resursive method. 29 | *
Recursion can be costly for large numbers. 30 | */ 31 | uint64_t double_factorial_recursive(uint64_t n) { 32 | if (n <= 1) 33 | return 1; 34 | return n * double_factorial_recursive(n - 2); 35 | } 36 | 37 | /** Wrapper to run tests using both recursive and iterative implementations. 38 | * The checks are only valid in debug builds due to the use of `assert()` 39 | * statements. 40 | * \param [in] n number to check double factorial for 41 | * \param [in] expected expected result 42 | */ 43 | void test(uint64_t n, uint64_t expected) { 44 | assert(double_factorial_iterative(n) == expected); 45 | assert(double_factorial_recursive(n) == expected); 46 | } 47 | 48 | /** 49 | * Test implementations 50 | */ 51 | void tests() { 52 | std::cout << "Test 1:\t n=5\t..."; 53 | test(5, 15); 54 | std::cout << "passed\n"; 55 | 56 | std::cout << "Test 2:\t n=15\t..."; 57 | test(15, 2027025); 58 | std::cout << "passed\n"; 59 | 60 | std::cout << "Test 3:\t n=0\t..."; 61 | test(0, 1); 62 | std::cout << "passed\n"; 63 | } 64 | 65 | /** 66 | * Main function 67 | */ 68 | int main() { 69 | tests(); 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /math/eulers_totient_function.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Implementation of [Euler's 4 | * Totient](https://en.wikipedia.org/wiki/Euler%27s_totient_function) 5 | * @description 6 | * Euler Totient Function is also known as phi function. 7 | * \f[\phi(n) = 8 | * \phi\left({p_1}^{a_1}\right)\cdot\phi\left({p_2}^{a_2}\right)\ldots\f] where 9 | * \f$p_1\f$, \f$p_2\f$, \f$\ldots\f$ are prime factors of n. 10 | *
3 Euler's properties: 11 | * 1. \f$\phi(n) = n-1\f$ 12 | * 2. \f$\phi(n^k) = n^k - n^{k-1}\f$ 13 | * 3. \f$\phi(a,b) = \phi(a)\cdot\phi(b)\f$ where a and b are relative primes. 14 | * 15 | * Applying this 3 properties on the first equation. 16 | * \f[\phi(n) = 17 | * n\cdot\left(1-\frac{1}{p_1}\right)\cdot\left(1-\frac{1}{p_2}\right)\cdots\f] 18 | * where \f$p_1\f$,\f$p_2\f$... are prime factors. 19 | * Hence Implementation in \f$O\left(\sqrt{n}\right)\f$. 20 | *
Some known values are: 21 | * * \f$\phi(100) = 40\f$ 22 | * * \f$\phi(1) = 1\f$ 23 | * * \f$\phi(17501) = 15120\f$ 24 | * * \f$\phi(1420) = 560\f$ 25 | * @author [Mann Mehta](https://github.com/mann2108) 26 | */ 27 | 28 | #include /// for assert 29 | #include 30 | #include /// for IO operations 31 | 32 | /** 33 | * @brief Mathematical algorithms 34 | * @namespace 35 | */ 36 | namespace math { 37 | /** 38 | * @brief Function to calculate Euler's Totient 39 | * @param n the number to find the Euler's Totient of 40 | */ 41 | uint64_t phiFunction(uint64_t n) { 42 | uint64_t result = n; 43 | for (uint64_t i = 2; i * i <= n; i++) { 44 | if (n % i != 0) 45 | continue; 46 | while (n % i == 0) n /= i; 47 | 48 | result -= result / i; 49 | } 50 | if (n > 1) 51 | result -= result / n; 52 | 53 | return result; 54 | } 55 | } // namespace math 56 | 57 | /** 58 | * @brief Self-test implementations 59 | * @returns void 60 | */ 61 | static void test() { 62 | assert(math::phiFunction(1) == 1); 63 | assert(math::phiFunction(2) == 1); 64 | assert(math::phiFunction(10) == 4); 65 | assert(math::phiFunction(123456) == 41088); 66 | assert(math::phiFunction(808017424794) == 263582333856); 67 | assert(math::phiFunction(3141592) == 1570792); 68 | assert(math::phiFunction(27182818) == 12545904); 69 | 70 | std::cout << "All tests have successfully passed!\n"; 71 | } 72 | 73 | /** 74 | * @brief Main function 75 | * @param argc commandline argument count (ignored) 76 | * @param argv commandline array of arguments (ignored) 77 | * @returns 0 on exit 78 | */ 79 | int main(int argc, char *argv[]) { 80 | test(); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /math/factorial.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Find the [factorial](https://en.wikipedia.org/wiki/Factorial) of a 4 | * given number 5 | * @details Calculate factorial via recursion 6 | * \f[n! = n\times(n-1)\times(n-2)\times(n-3)\times\ldots\times3\times2\times1 7 | * = n\times(n-1)!\f] 8 | * for example: 9 | * \f$5! = 5\times4! = 5\times4\times3\times2\times1 = 120\f$ 10 | * 11 | * @author [Akshay Gupta](https://github.com/Akshay1910) 12 | */ 13 | 14 | #include /// for assert 15 | #include 16 | #include /// for I/O operations 17 | /** 18 | * @namespace 19 | * @brief Mathematical algorithms 20 | */ 21 | namespace math { 22 | 23 | /** 24 | * @brief function to find factorial of given number 25 | * @param n is the number which is to be factorialized 26 | * @warning Maximum value for the parameter is 20 as 21! 27 | * cannot be represented in 64 bit unsigned int 28 | */ 29 | uint64_t factorial(uint8_t n) { 30 | if (n > 20) { 31 | throw std::invalid_argument("maximum value is 20\n"); 32 | } 33 | if (n == 0) { 34 | return 1; 35 | } 36 | return n * factorial(n - 1); 37 | } 38 | } // namespace math 39 | 40 | /** 41 | * @brief Self-test implementations 42 | * @returns void 43 | */ 44 | static void tests() { 45 | assert(math::factorial(1) == 1); 46 | assert(math::factorial(0) == 1); 47 | assert(math::factorial(5) == 120); 48 | assert(math::factorial(10) == 3628800); 49 | assert(math::factorial(20) == 2432902008176640000); 50 | std::cout << "All tests have passed successfully!\n"; 51 | } 52 | 53 | /** 54 | * @brief Main function 55 | * @returns 0 on exit 56 | */ 57 | int main() { 58 | tests(); // run self-test implementations 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /math/fibonacci.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief n-th [Fibonacci 4 | * number](https://en.wikipedia.org/wiki/Fibonacci_sequence). 5 | * 6 | * @details 7 | * Naive recursive implementation to calculate the n-th Fibonacci number. 8 | * \f[\text{fib}(n) = \text{fib}(n-1) + \text{fib}(n-2)\f] 9 | * 10 | * @see fibonacci_large.cpp, fibonacci_fast.cpp, string_fibonacci.cpp 11 | */ 12 | 13 | #include 14 | #include /// for assert 15 | #include /// for IO operations 16 | 17 | /** 18 | * @namespace math 19 | * @brief Math algorithms 20 | */ 21 | namespace math { 22 | /** 23 | * @namespace fibonacci 24 | * @brief Functions for Fibonacci sequence 25 | */ 26 | namespace fibonacci { 27 | /** 28 | * @brief Function to compute the n-th Fibonacci number 29 | * @param n the index of the Fibonacci number 30 | * @returns n-th element of the Fibonacci's sequence 31 | */ 32 | uint64_t fibonacci(uint64_t n) { 33 | // If the input is 0 or 1 just return the same (Base Case) 34 | // This will set the first 2 values of the sequence 35 | if (n <= 1) { 36 | return n; 37 | } 38 | 39 | // Add the preceding 2 values of the sequence to get next 40 | return fibonacci(n - 1) + fibonacci(n - 2); 41 | } 42 | } // namespace fibonacci 43 | } // namespace math 44 | 45 | /** 46 | * @brief Self-test implementation 47 | * @returns `void` 48 | */ 49 | static void test() { 50 | assert(math::fibonacci::fibonacci(0) == 0); 51 | assert(math::fibonacci::fibonacci(1) == 1); 52 | assert(math::fibonacci::fibonacci(2) == 1); 53 | assert(math::fibonacci::fibonacci(3) == 2); 54 | assert(math::fibonacci::fibonacci(4) == 3); 55 | assert(math::fibonacci::fibonacci(15) == 610); 56 | assert(math::fibonacci::fibonacci(20) == 6765); 57 | std::cout << "All tests have passed successfully!\n"; 58 | } 59 | 60 | /** 61 | * @brief Main function 62 | * @returns 0 on exit 63 | */ 64 | int main() { 65 | test(); // run self-test implementations 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /math/gcd_iterative_euclidean.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Compute the greatest common denominator of two integers using 4 | * *iterative form* of 5 | * [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm) 6 | * 7 | * @see gcd_recursive_euclidean.cpp, gcd_of_n_numbers.cpp 8 | */ 9 | #include 10 | #include 11 | 12 | /** 13 | * algorithm 14 | */ 15 | int gcd(int num1, int num2) { 16 | if (num1 <= 0 | num2 <= 0) { 17 | throw std::domain_error("Euclidean algorithm domain is for ints > 0"); 18 | } 19 | 20 | if (num1 == num2) { 21 | return num1; 22 | } 23 | 24 | int base_num = 0; 25 | int previous_remainder = 1; 26 | 27 | if (num1 > num2) { 28 | base_num = num1; 29 | previous_remainder = num2; 30 | } else { 31 | base_num = num2; 32 | previous_remainder = num1; 33 | } 34 | 35 | while ((base_num % previous_remainder) != 0) { 36 | int old_base = base_num; 37 | base_num = previous_remainder; 38 | previous_remainder = old_base % previous_remainder; 39 | } 40 | 41 | return previous_remainder; 42 | } 43 | 44 | /** 45 | * Main function 46 | */ 47 | int main() { 48 | std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl; 49 | try { 50 | std::cout << "gcd of -120,10 is " << gcd(-120, 10) << std::endl; 51 | } catch (const std::domain_error &e) { 52 | std::cout << "Error handling was successful" << std::endl; 53 | } 54 | std::cout << "gcd of 312,221 is " << (gcd(312, 221)) << std::endl; 55 | std::cout << "gcd of 289,204 is " << (gcd(289, 204)) << std::endl; 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /math/gcd_recursive_euclidean.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Compute the greatest common denominator of two integers using 4 | * *recursive form* of 5 | * [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm) 6 | * 7 | * @see gcd_iterative_euclidean.cpp, gcd_of_n_numbers.cpp 8 | */ 9 | #include 10 | 11 | /** 12 | * algorithm 13 | */ 14 | int gcd(int num1, int num2) { 15 | if (num1 <= 0 | num2 <= 0) { 16 | throw std::domain_error("Euclidean algorithm domain is for ints > 0"); 17 | } 18 | 19 | if (num1 == num2) { 20 | return num1; 21 | } 22 | 23 | // Everything divides 0 24 | if (num1 == 0) 25 | return num2; 26 | if (num2 == 0) 27 | return num1; 28 | 29 | // base case 30 | if (num1 == num2) 31 | return num1; 32 | 33 | // a is greater 34 | if (num1 > num2) 35 | return gcd(num1 - num2, num2); 36 | return gcd(num1, num2 - num1); 37 | } 38 | 39 | /** 40 | * Main function 41 | */ 42 | int main() { 43 | std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl; 44 | try { 45 | std::cout << "gcd of -120,10 is " << gcd(-120, 10) << std::endl; 46 | } catch (const std::domain_error &e) { 47 | std::cout << "Error handling was successful" << std::endl; 48 | } 49 | std::cout << "gcd of 312,221 is " << (gcd(312, 221)) << std::endl; 50 | std::cout << "gcd of 289,204 is " << (gcd(289, 204)) << std::endl; 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /math/largest_power.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Algorithm to find largest x such that p^x divides n! (factorial) using 4 | * Legendre's Formula. 5 | * @details Given an integer n and a prime number p, the task is to find the 6 | * largest x such that p^x (p raised to power x) divides n! (factorial). This 7 | * will be done using Legendre's formula: x = [n/(p^1)] + [n/(p^2)] + [n/(p^3)] 8 | * + \ldots + 1 9 | * @see more on 10 | * https://math.stackexchange.com/questions/141196/highest-power-of-a-prime-p-dividing-n 11 | * @author [uday6670](https://github.com/uday6670) 12 | */ 13 | 14 | #include /// for assert 15 | #include 16 | #include /// for std::cin and std::cout 17 | /** 18 | * @namespace math 19 | * @brief Mathematical algorithms 20 | */ 21 | namespace math { 22 | 23 | /** 24 | * @brief Function to calculate largest power 25 | * @param n number 26 | * @param p prime number 27 | * @returns largest power 28 | */ 29 | uint64_t largestPower(uint32_t n, const uint16_t& p) { 30 | // Initialize result 31 | int x = 0; 32 | 33 | // Calculate result 34 | while (n) { 35 | n /= p; 36 | x += n; 37 | } 38 | return x; 39 | } 40 | 41 | } // namespace math 42 | 43 | /** 44 | * @brief Function for testing largestPower function. 45 | * test cases and assert statement. 46 | * @returns `void` 47 | */ 48 | static void test() { 49 | uint8_t test_case_1 = math::largestPower(5, 2); 50 | assert(test_case_1 == 3); 51 | std::cout << "Test 1 Passed!" << std::endl; 52 | 53 | uint16_t test_case_2 = math::largestPower(10, 3); 54 | assert(test_case_2 == 4); 55 | std::cout << "Test 2 Passed!" << std::endl; 56 | 57 | uint32_t test_case_3 = math::largestPower(25, 5); 58 | assert(test_case_3 == 6); 59 | std::cout << "Test 3 Passed!" << std::endl; 60 | 61 | uint32_t test_case_4 = math::largestPower(27, 2); 62 | assert(test_case_4 == 23); 63 | std::cout << "Test 4 Passed!" << std::endl; 64 | 65 | uint16_t test_case_5 = math::largestPower(7, 3); 66 | assert(test_case_5 == 2); 67 | std::cout << "Test 5 Passed!" << std::endl; 68 | } 69 | 70 | /** 71 | * @brief Main function 72 | * @returns 0 on exit 73 | */ 74 | int main() { 75 | test(); // execute the tests 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /math/least_common_multiple.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020 @author tjgurwara99 3 | * @file 4 | * 5 | * A basic implementation of LCM function 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | /** 12 | * Function for finding greatest common divisor of two numbers. 13 | * @params two integers x and y whose gcd we want to find. 14 | * @return greatest common divisor of x and y. 15 | */ 16 | unsigned int gcd(unsigned int x, unsigned int y) { 17 | if (x == 0) { 18 | return y; 19 | } 20 | if (y == 0) { 21 | return x; 22 | } 23 | if (x == y) { 24 | return x; 25 | } 26 | if (x > y) { 27 | // The following is valid because we have checked whether y == 0 28 | 29 | unsigned int temp = x / y; 30 | return gcd(y, x - temp * y); 31 | } 32 | // Again the following is valid because we have checked whether x == 0 33 | 34 | unsigned int temp = y / x; 35 | return gcd(x, y - temp * x); 36 | } 37 | 38 | /** 39 | * Function for finding the least common multiple of two numbers. 40 | * @params integer x and y whose lcm we want to find. 41 | * @return lcm of x and y using the relation x * y = gcd(x, y) * lcm(x, y) 42 | */ 43 | unsigned int lcm(unsigned int x, unsigned int y) { 44 | return x / gcd(x, y) * y; 45 | } 46 | 47 | /** 48 | * Function for testing the lcm() functions with some assert statements. 49 | */ 50 | void tests() { 51 | // First test on lcm(5,10) == 10 52 | assert(((void)"LCM of 5 and 10 is 10 but lcm function gives a different " 53 | "result.\n", 54 | lcm(5, 10) == 10)); 55 | std::cout << "First assertion passes: LCM of 5 and 10 is " << lcm(5, 10) 56 | << std::endl; 57 | 58 | // Second test on lcm(2,3) == 6 as 2 and 3 are coprime (prime in fact) 59 | assert(((void)"LCM of 2 and 3 is 6 but lcm function gives a different " 60 | "result.\n", 61 | lcm(2, 3) == 6)); 62 | std::cout << "Second assertion passes: LCM of 2 and 3 is " << lcm(2, 3) 63 | << std::endl; 64 | 65 | // Testing an integer overflow. 66 | // The algorithm should work as long as the result fits into integer. 67 | assert(((void)"LCM of 987654321 and 987654321 is 987654321 but lcm function" 68 | " gives a different result.\n", 69 | lcm(987654321, 987654321) == 987654321)); 70 | std::cout << "Third assertion passes: LCM of 987654321 and 987654321 is " 71 | << lcm(987654321, 987654321) 72 | << std::endl; 73 | } 74 | 75 | /** 76 | * Main function 77 | */ 78 | int main() { 79 | tests(); 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /math/magic_number.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief A simple program to check if the given number is a magic number or 4 | * not. A number is said to be a magic number, if the sum of its digits are 5 | * calculated till a single digit recursively by adding the sum of the digits 6 | * after every addition. If the single digit comes out to be 1,then the number 7 | * is a magic number. 8 | * 9 | * This is a shortcut method to verify Magic Number. 10 | * On dividing the input by 9, if the remainder is 1 then the number is a magic 11 | * number else not. The divisibility rule of 9 says that a number is divisible 12 | * by 9 if the sum of its digits are also divisible by 9. Therefore, if a number 13 | * is divisible by 9, then, recursively, all the digit sums are also divisible 14 | * by 9. The final digit sum is always 9. An increase of 1 in the original 15 | * number will increase the ultimate value by 1, making it 10 and the ultimate 16 | * sum will be 1, thus verifying that it is a magic number. 17 | * @author [Neha Hasija](https://github.com/neha-hasija17) 18 | */ 19 | #include /// for assert 20 | #include 21 | #include /// for io operations 22 | 23 | /** 24 | * @namespace math 25 | * @brief Mathematical algorithms 26 | */ 27 | namespace math { 28 | /** 29 | * Function to check if the given number is magic number or not. 30 | * @param n number to be checked. 31 | * @return if number is a magic number, returns true, else false. 32 | */ 33 | bool magic_number(const uint64_t &n) { 34 | if (n <= 0) { 35 | return false; 36 | } 37 | // result stores the modulus of @param n with 9 38 | uint64_t result = n % 9; 39 | // if result is 1 then the number is a magic number else not 40 | if (result == 1) { 41 | return true; 42 | } else { 43 | return false; 44 | } 45 | } 46 | } // namespace math 47 | 48 | /** 49 | * @brief Test function 50 | * @returns void 51 | */ 52 | static void tests() { 53 | std::cout << "Test 1:\t n=60\n"; 54 | assert(math::magic_number(60) == false); 55 | std::cout << "passed\n"; 56 | 57 | std::cout << "Test 2:\t n=730\n"; 58 | assert(math::magic_number(730) == true); 59 | std::cout << "passed\n"; 60 | 61 | std::cout << "Test 3:\t n=0\n"; 62 | assert(math::magic_number(0) == false); 63 | std::cout << "passed\n"; 64 | 65 | std::cout << "Test 4:\t n=479001600\n"; 66 | assert(math::magic_number(479001600) == false); 67 | std::cout << "passed\n"; 68 | 69 | std::cout << "Test 5:\t n=-35\n"; 70 | assert(math::magic_number(-35) == false); 71 | std::cout << "passed\n"; 72 | } 73 | 74 | /** 75 | * @brief Main function 76 | * @returns 0 on exit 77 | */ 78 | int main() { 79 | tests(); // execute the tests 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /math/modular_exponentiation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief C++ Program for Modular Exponentiation Iteratively. 4 | * @details The task is to calculate the value of an integer a raised to an 5 | * integer exponent b under modulo c. 6 | * @note The time complexity of this approach is O(log b). 7 | * 8 | * Example: 9 | * (4^3) % 5 (where ^ stands for exponentiation and % for modulo) 10 | * (4*4*4) % 5 11 | * (4 % 5) * ( (4*4) % 5 ) 12 | * 4 * (16 % 5) 13 | * 4 * 1 14 | * 4 15 | * We can also verify the result as 4^3 is 64 and 64 modulo 5 is 4 16 | * 17 | * @author [Shri2206](https://github.com/Shri2206) 18 | */ 19 | #include /// for assert 20 | #include 21 | #include /// for io operations 22 | /** 23 | * @namespace math 24 | * @brief Mathematical algorithms 25 | */ 26 | namespace math { 27 | /** 28 | * @brief This function calculates a raised to exponent b under modulo c using 29 | * modular exponentiation. 30 | * @param a integer base 31 | * @param b unsigned integer exponent 32 | * @param c integer modulo 33 | * @return a raised to power b modulo c 34 | */ 35 | uint64_t power(uint64_t a, uint64_t b, uint64_t c) { 36 | uint64_t ans = 1; /// Initialize the answer to be returned 37 | a = a % c; /// Update a if it is more than or equal to c 38 | if (a == 0) { 39 | return 0; /// In case a is divisible by c; 40 | } 41 | while (b > 0) { 42 | /// If b is odd, multiply a with answer 43 | if (b & 1) { 44 | ans = ((ans % c) * (a % c)) % c; 45 | } 46 | /// b must be even now 47 | b = b >> 1; /// b = b/2 48 | a = ((a % c) * (a % c)) % c; 49 | } 50 | return ans; 51 | } 52 | 53 | } // namespace math 54 | 55 | /** 56 | * Function for testing power function. 57 | * test cases and assert statement. 58 | * @returns `void` 59 | */ 60 | static void test() { 61 | uint32_t test_case_1 = math::power(2, 5, 13); 62 | assert(test_case_1 == 6); 63 | std::cout << "Test 1 Passed!" << std::endl; 64 | 65 | uint32_t test_case_2 = math::power(14, 7, 15); 66 | assert(test_case_2 == 14); 67 | std::cout << "Test 2 Passed!" << std::endl; 68 | 69 | uint64_t test_case_3 = math::power(8, 15, 41); 70 | assert(test_case_3 == 32); 71 | std::cout << "Test 3 Passed!" << std::endl; 72 | 73 | uint64_t test_case_4 = math::power(27, 2, 5); 74 | assert(test_case_4 == 4); 75 | std::cout << "Test 4 Passed!" << std::endl; 76 | 77 | uint16_t test_case_5 = math::power(7, 3, 6); 78 | assert(test_case_5 == 1); 79 | std::cout << "Test 5 Passed!" << std::endl; 80 | } 81 | 82 | /** 83 | * @brief Main function 84 | * @returns 0 on exit 85 | */ 86 | int main() { 87 | test(); // execute the tests 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /math/modular_inverse_simple.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Simple implementation of [modular multiplicative 4 | * inverse](https://en.wikipedia.org/wiki/Modular_multiplicative_inverse) 5 | * 6 | * @details 7 | * this algorithm calculates the modular inverse x^{-1} \mod y iteratively 8 | */ 9 | 10 | #include /// for assert 11 | #include 12 | #include /// for IO operations 13 | 14 | /** 15 | * @brief Function imod 16 | * Calculates the modular inverse of x with respect to y, x^{-1} \mod y 17 | * @param x number 18 | * @param y number 19 | * @returns the modular inverse 20 | */ 21 | uint64_t imod(uint64_t x, uint64_t y) { 22 | uint64_t aux = 0; // auxiliary variable 23 | uint64_t itr = 0; // iteration counter 24 | 25 | do { // run the algorithm while not find the inverse 26 | aux = y * itr + 1; 27 | itr++; 28 | } while (aux % x); // while module aux % x non-zero 29 | 30 | return aux / x; 31 | } 32 | 33 | /** 34 | * @brief self-test implementations 35 | * @returns void 36 | */ 37 | static void test() { 38 | std::cout << "First case testing... \n"; 39 | // for a = 3 and b = 11 return 4 40 | assert(imod(3, 11) == 4); 41 | std::cout << "\nPassed!\n"; 42 | 43 | std::cout << "Second case testing... \n"; 44 | // for a = 3 and b = 26 return 9 45 | assert(imod(3, 26) == 9); 46 | std::cout << "\nPassed!\n"; 47 | 48 | std::cout << "Third case testing... \n"; 49 | // for a = 7 and b = 26 return 15 50 | assert(imod(7, 26) == 15); 51 | std::cout << "\nPassed!\n"; 52 | 53 | std::cout << "\nAll test cases have successfully passed!\n"; 54 | } 55 | /** 56 | * @brief Main function 57 | * @returns 0 on exit 58 | */ 59 | int main() { 60 | test(); // run self-test implementations 61 | }; 62 | -------------------------------------------------------------------------------- /math/power_for_huge_numbers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Compute powers of large numbers 4 | */ 5 | #include 6 | 7 | /** Maximum number of digits in output 8 | * \f$x^n\f$ where \f$1 <= x,\; n <= 10000\f$ and overflow may happen 9 | */ 10 | #define MAX 100000 11 | 12 | /** This function multiplies x 13 | * with the number represented by res[]. 14 | * res_size is size of res[] or 15 | * number of digits in the number 16 | * represented by res[]. This function 17 | * uses simple school mathematics 18 | * for multiplication. 19 | * This function may value of res_size 20 | * and returns the new value of res_size 21 | * @param x multiplicand 22 | * @param res large number representation using array 23 | * @param res_size number of digits in `res` 24 | */ 25 | int multiply(int x, int res[], int res_size) { 26 | // Initialize carry 27 | int carry = 0; 28 | 29 | // One by one multiply n with 30 | // individual digits of res[] 31 | for (int i = 0; i < res_size; i++) { 32 | int prod = res[i] * x + carry; 33 | 34 | // Store last digit of 35 | // 'prod' in res[] 36 | res[i] = prod % 10; 37 | 38 | // Put rest in carry 39 | carry = prod / 10; 40 | } 41 | 42 | // Put carry in res and 43 | // increase result size 44 | while (carry) { 45 | res[res_size] = carry % 10; 46 | carry = carry / 10; 47 | res_size++; 48 | } 49 | return res_size; 50 | } 51 | 52 | /** This function finds power of a number x and print \f$x^n\f$ 53 | * @param x base 54 | * @param n exponent 55 | */ 56 | void power(int x, int n) { 57 | // printing value "1" for power = 0 58 | if (n == 0) { 59 | std::cout << "1"; 60 | return; 61 | } 62 | 63 | int res[MAX]; 64 | int res_size = 0; 65 | int temp = x; 66 | 67 | // Initialize result 68 | while (temp != 0) { 69 | res[res_size++] = temp % 10; 70 | temp = temp / 10; 71 | } 72 | 73 | // Multiply x n times 74 | // (x^n = x*x*x....n times) 75 | for (int i = 2; i <= n; i++) res_size = multiply(x, res, res_size); 76 | 77 | std::cout << x << "^" << n << " = "; 78 | for (int i = res_size - 1; i >= 0; i--) std::cout << res[i]; 79 | } 80 | 81 | /** Main function */ 82 | int main() { 83 | int exponent, base; 84 | std::cout << "Enter base "; 85 | std::cin >> base; 86 | std::cout << "Enter exponent "; 87 | std::cin >> exponent; 88 | power(base, exponent); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /math/prime_factorization.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Prime factorization of positive integers 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /** Declaring variables for maintaing prime numbers and to check whether a 11 | * number is prime or not 12 | */ 13 | bool isprime[1000006]; 14 | 15 | /** list of prime numbers */ 16 | std::vector prime_numbers; 17 | 18 | /** list of prime factor-pairs */ 19 | std::vector> factors; 20 | 21 | /** Calculating prime number upto a given range 22 | */ 23 | void SieveOfEratosthenes(int N) { 24 | // initializes the array isprime 25 | memset(isprime, true, sizeof isprime); 26 | 27 | for (int i = 2; i <= N; i++) { 28 | if (isprime[i]) { 29 | for (int j = 2 * i; j <= N; j += i) isprime[j] = false; 30 | } 31 | } 32 | 33 | for (int i = 2; i <= N; i++) { 34 | if (isprime[i]) 35 | prime_numbers.push_back(i); 36 | } 37 | } 38 | 39 | /** Prime factorization of a number */ 40 | void prime_factorization(int num) { 41 | int number = num; 42 | 43 | for (int i = 0; prime_numbers[i] <= num; i++) { 44 | int count = 0; 45 | 46 | // termination condition 47 | if (number == 1) { 48 | break; 49 | } 50 | 51 | while (number % prime_numbers[i] == 0) { 52 | count++; 53 | number = number / prime_numbers[i]; 54 | } 55 | 56 | if (count) 57 | factors.push_back(std::make_pair(prime_numbers[i], count)); 58 | } 59 | } 60 | 61 | /** Main program */ 62 | int main() { 63 | int num; 64 | std::cout << "\t\tComputes the prime factorization\n\n"; 65 | std::cout << "Type in a number: "; 66 | std::cin >> num; 67 | 68 | SieveOfEratosthenes(num); 69 | 70 | prime_factorization(num); 71 | 72 | // Prime factors with their powers in the given number in new line 73 | for (auto it : factors) { 74 | std::cout << it.first << " " << it.second << std::endl; 75 | } 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /math/prime_numbers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Get list of prime numbers 4 | * @see primes_up_to_billion.cpp sieve_of_eratosthenes.cpp 5 | */ 6 | #include 7 | #include 8 | 9 | /** Generate an increasingly large number of primes 10 | * and store in a list 11 | */ 12 | std::vector primes(size_t max) { 13 | std::vector res; 14 | std::vector is_not_prime(max + 1, false); 15 | for (size_t i = 2; i <= max; i++) { 16 | if (!is_not_prime[i]) { 17 | res.emplace_back(i); 18 | } 19 | for (int p : res) { 20 | size_t k = i * p; 21 | if (k > max) { 22 | break; 23 | } 24 | is_not_prime[k] = true; 25 | if (i % p == 0) { 26 | break; 27 | } 28 | } 29 | } 30 | return res; 31 | } 32 | 33 | /** main function */ 34 | int main() { 35 | std::cout << "Calculate primes up to:\n>> "; 36 | int n = 0; 37 | std::cin >> n; 38 | std::vector ans = primes(n); 39 | for (int p : ans) std::cout << p << ' '; 40 | std::cout << std::endl; 41 | } 42 | -------------------------------------------------------------------------------- /math/primes_up_to_billion.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Compute prime numbers upto 1 billion 4 | * @see prime_numbers.cpp sieve_of_eratosthenes.cpp 5 | */ 6 | #include 7 | #include 8 | 9 | /** array to store the primes */ 10 | char prime[100000000]; 11 | 12 | /** Perform Sieve algorithm */ 13 | void Sieve(int64_t n) { 14 | memset(prime, '1', sizeof(prime)); // intitize '1' to every index 15 | prime[0] = '0'; // 0 is not prime 16 | prime[1] = '0'; // 1 is not prime 17 | for (int64_t p = 2; p * p <= n; p++) { 18 | if (prime[p] == '1') { 19 | for (int64_t i = p * p; i <= n; i += p) 20 | prime[i] = '0'; // set all multiples of p to false 21 | } 22 | } 23 | } 24 | 25 | /** Main function */ 26 | int main() { 27 | Sieve(100000000); 28 | int64_t n; 29 | std::cin >> n; // 10006187 30 | if (prime[n] == '1') 31 | std::cout << "YES\n"; 32 | else 33 | std::cout << "NO\n"; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /math/sqrt_double.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Calculate the square root of any positive real number in \f$O(\log 4 | * N)\f$ time, with precision fixed using [bisection 5 | * method](https://en.wikipedia.org/wiki/Bisection_method) of root-finding. 6 | * 7 | * @see Can be implemented using faster and better algorithms like 8 | * newton_raphson_method.cpp and false_position.cpp 9 | */ 10 | #include 11 | #include 12 | 13 | /** Bisection method implemented for the function \f$x^2-a=0\f$ 14 | * whose roots are \f$\pm\sqrt{a}\f$ and only the positive root is returned. 15 | */ 16 | double Sqrt(double a) { 17 | if (a > 0 && a < 1) { 18 | return 1 / Sqrt(1 / a); 19 | } 20 | double l = 0, r = a; 21 | /* Epsilon is the precision. 22 | A great precision is 23 | between 1e-7 and 1e-12. 24 | double epsilon = 1e-12; 25 | */ 26 | double epsilon = 1e-12; 27 | while (l <= r) { 28 | double mid = (l + r) / 2; 29 | if (mid * mid > a) { 30 | r = mid; 31 | } else { 32 | if (a - mid * mid < epsilon) { 33 | return mid; 34 | } 35 | l = mid; 36 | } 37 | } 38 | return -1; 39 | } 40 | 41 | /** main function */ 42 | int main() { 43 | double n{}; 44 | std::cin >> n; 45 | assert(n >= 0); 46 | // Change this line for a better precision 47 | std::cout.precision(12); 48 | std::cout << std::fixed << Sqrt(n); 49 | } 50 | -------------------------------------------------------------------------------- /math/string_fibonacci.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief This Programme returns the Nth fibonacci as a string. 4 | * 5 | * The method used is manual addition with carry and placing it in a string 6 | * which is called string addition This makes it have no bounds or limits 7 | * 8 | * @see fibonacci_large.cpp, fibonacci_fast.cpp, fibonacci.cpp 9 | */ 10 | 11 | #include 12 | #include 13 | #ifdef _MSC_VER 14 | #include // use this for MS Visual C 15 | #else 16 | #include // otherwise 17 | #endif 18 | 19 | /** 20 | * function to add two string numbers 21 | * \param [in] a first number in string to add 22 | * \param [in] b second number in string to add 23 | * \returns sum as a std::string 24 | */ 25 | std::string add(std::string a, std::string b) { 26 | std::string temp = ""; 27 | 28 | // carry flag 29 | int carry = 0; 30 | 31 | // fills up with zeros 32 | while (a.length() < b.length()) { 33 | a = "0" + a; 34 | } 35 | 36 | // fills up with zeros 37 | while (b.length() < a.length()) { 38 | b = "0" + b; 39 | } 40 | 41 | // adds the numbers a and b 42 | for (int i = a.length() - 1; i >= 0; i--) { 43 | char val = static_cast(((a[i] - 48) + (b[i] - 48)) + 48 + carry); 44 | if (val > 57) { 45 | carry = 1; 46 | val -= 10; 47 | } else { 48 | carry = 0; 49 | } 50 | temp = val + temp; 51 | } 52 | 53 | // processes the carry flag 54 | if (carry == 1) { 55 | temp = "1" + temp; 56 | } 57 | 58 | // removes leading zeros. 59 | while (temp[0] == '0' && temp.length() > 1) { 60 | temp = temp.substr(1); 61 | } 62 | 63 | return temp; 64 | } 65 | 66 | /** Fibonacci iterator 67 | * \param [in] n n^th Fibonacci number 68 | */ 69 | void fib_Accurate(uint64_t n) { 70 | std::string tmp = ""; 71 | std::string fibMinus1 = "1"; 72 | std::string fibMinus2 = "0"; 73 | for (uint64_t i = 0; i < n; i++) { 74 | tmp = add(fibMinus1, fibMinus2); 75 | fibMinus2 = fibMinus1; 76 | fibMinus1 = tmp; 77 | } 78 | std::cout << fibMinus2; 79 | } 80 | 81 | /** main function */ 82 | int main() { 83 | int n; 84 | std::cout << "Enter whatever number N you want to find the fibonacci of\n"; 85 | std::cin >> n; 86 | std::cout << n << " th Fibonacci is \n"; 87 | fib_Accurate(n); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /math/sum_of_binomial_coefficient.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Algorithm to find sum of binomial coefficients of a given positive 4 | * integer. 5 | * @details Given a positive integer n, the task is to find the sum of binomial 6 | * coefficient i.e nC0 + nC1 + nC2 + ... + nCn-1 + nCn By induction, we can 7 | * prove that the sum is equal to 2^n 8 | * @see more on 9 | * https://en.wikipedia.org/wiki/Binomial_coefficient#Sums_of_the_binomial_coefficients 10 | * @author [muskan0719](https://github.com/muskan0719) 11 | */ 12 | #include /// for assert 13 | #include 14 | #include /// for std::cin and std::cout 15 | 16 | /** 17 | * @namespace math 18 | * @brief Mathematical algorithms 19 | */ 20 | namespace math { 21 | 22 | /** 23 | * Function to calculate sum of binomial coefficients 24 | * @param n number 25 | * @return Sum of binomial coefficients of number 26 | */ 27 | uint64_t binomialCoeffSum(uint64_t n) { 28 | // Calculating 2^n 29 | return (1 << n); 30 | } 31 | } // namespace math 32 | 33 | /** 34 | * Function for testing binomialCoeffSum function. 35 | * test cases and assert statement. 36 | * @returns `void` 37 | */ 38 | static void test() { 39 | int test_case_1 = math::binomialCoeffSum(2); 40 | assert(test_case_1 == 4); 41 | std::cout << "Test_case_1 Passed!" << std::endl; 42 | 43 | int test_case_2 = math::binomialCoeffSum(3); 44 | assert(test_case_2 == 8); 45 | std::cout << "Test_case_2 Passed!" << std::endl; 46 | 47 | int test_case_3 = math::binomialCoeffSum(4); 48 | assert(test_case_3 == 16); 49 | std::cout << "Test_case_3 Passed!" << std::endl; 50 | 51 | int test_case_4 = math::binomialCoeffSum(5); 52 | assert(test_case_4 == 32); 53 | std::cout << "Test_case_4 Passed!" << std::endl; 54 | 55 | int test_case_5 = math::binomialCoeffSum(7); 56 | assert(test_case_5 == 128); 57 | std::cout << "Test_case_5 Passed!" << std::endl; 58 | } 59 | 60 | /** 61 | * @brief Main function 62 | * @returns 0 on exit 63 | */ 64 | int main() { 65 | test(); // execute the tests 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /math/sum_of_digits.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020 @author iamnambiar 3 | * 4 | * @file 5 | * \brief A C++ Program to find the Sum of Digits of input integer. 6 | */ 7 | #include 8 | #include 9 | 10 | /** 11 | * Function to find the sum of the digits of an integer. 12 | * @param num The integer. 13 | * @return Sum of the digits of the integer. 14 | * 15 | * \detail 16 | * First the algorithm check whether the num is negative or positive, 17 | * if it is negative, then we neglect the negative sign. 18 | * Next, the algorithm extract the last digit of num by dividing by 10 19 | * and extracting the remainder and this is added to the sum. 20 | * The number is then divided by 10 to remove the last digit. 21 | * This loop continues until num becomes 0. 22 | */ 23 | int sum_of_digits(int num) { 24 | // If num is negative then negative sign is neglected. 25 | if (num < 0) { 26 | num = -1 * num; 27 | } 28 | int sum = 0; 29 | while (num > 0) { 30 | sum = sum + (num % 10); 31 | num = num / 10; 32 | } 33 | return sum; 34 | } 35 | 36 | /** 37 | * Function for testing the sum_of_digits() function with a 38 | * first test case of 119765 and assert statement. 39 | */ 40 | void test1() { 41 | int test_case_1 = sum_of_digits(119765); 42 | assert(test_case_1 == 29); 43 | } 44 | 45 | /** 46 | * Function for testing the sum_of_digits() function with a 47 | * second test case of -12256 and assert statement. 48 | */ 49 | void test2() { 50 | int test_case_2 = sum_of_digits(-12256); 51 | assert(test_case_2 == 16); 52 | } 53 | 54 | /** 55 | * Function for testing the sum_of_digits() with 56 | * all the test cases. 57 | */ 58 | void test() { 59 | // First test. 60 | test1(); 61 | // Second test. 62 | test2(); 63 | } 64 | 65 | /** 66 | * Main Function 67 | */ 68 | int main() { 69 | test(); 70 | std::cout << "Success." << std::endl; 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /numerical_methods/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/numerical_methods") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /numerical_methods/bisection_method.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * \brief Solve the equation \f$f(x)=0\f$ using [bisection 4 | * method](https://en.wikipedia.org/wiki/Bisection_method) 5 | * 6 | * Given two points \f$a\f$ and \f$b\f$ such that \f$f(a)<0\f$ and 7 | * \f$f(b)>0\f$, then the \f$(i+1)^\text{th}\f$ approximation is given by: \f[ 8 | * x_{i+1} = \frac{a_i+b_i}{2} 9 | * \f] 10 | * For the next iteration, the interval is selected 11 | * as: \f$[a,x]\f$ if \f$x>0\f$ or \f$[x,b]\f$ if \f$x<0\f$. The Process is 12 | * continued till a close enough approximation is achieved. 13 | * 14 | * \see newton_raphson_method.cpp, false_position.cpp, secant_method.cpp 15 | */ 16 | #include 17 | #include 18 | #include 19 | 20 | #define EPSILON \ 21 | 1e-6 // std::numeric_limits::epsilon() ///< system accuracy limit 22 | #define MAX_ITERATIONS 50000 ///< Maximum number of iterations to check 23 | 24 | /** define \f$f(x)\f$ to find root for 25 | */ 26 | static double eq(double i) { 27 | return (std::pow(i, 3) - (4 * i) - 9); // original equation 28 | } 29 | 30 | /** get the sign of any given number */ 31 | template 32 | int sgn(T val) { 33 | return (T(0) < val) - (val < T(0)); 34 | } 35 | 36 | /** main function */ 37 | int main() { 38 | double a = -1, b = 1, x, z; 39 | int i; 40 | 41 | // loop to find initial intervals a, b 42 | for (int i = 0; i < MAX_ITERATIONS; i++) { 43 | z = eq(a); 44 | x = eq(b); 45 | if (sgn(z) == sgn(x)) { // same signs, increase interval 46 | b++; 47 | a--; 48 | } else { // if opposite signs, we got our interval 49 | break; 50 | } 51 | } 52 | 53 | std::cout << "\nFirst initial: " << a; 54 | std::cout << "\nSecond initial: " << b; 55 | 56 | // start iterations 57 | for (i = 0; i < MAX_ITERATIONS; i++) { 58 | x = (a + b) / 2; 59 | z = eq(x); 60 | std::cout << "\n\nz: " << z << "\t[" << a << " , " << b 61 | << " | Bisect: " << x << "]"; 62 | 63 | if (z < 0) { 64 | a = x; 65 | } else { 66 | b = x; 67 | } 68 | 69 | if (std::abs(z) < EPSILON) // stoping criteria 70 | break; 71 | } 72 | 73 | std::cout << "\n\nRoot: " << x << "\t\tSteps: " << i << std::endl; 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /numerical_methods/gaussian_elimination.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * \brief [Gaussian elimination 4 | * method](https://en.wikipedia.org/wiki/Gaussian_elimination) 5 | */ 6 | #include 7 | 8 | /** Main function */ 9 | int main() { 10 | int mat_size, i, j, step; 11 | 12 | std::cout << "Matrix size: "; 13 | std::cin >> mat_size; 14 | 15 | // create a 2D matrix by dynamic memory allocation 16 | double **mat = new double *[mat_size + 1], **x = new double *[mat_size]; 17 | for (i = 0; i <= mat_size; i++) { 18 | mat[i] = new double[mat_size + 1]; 19 | if (i < mat_size) 20 | x[i] = new double[mat_size + 1]; 21 | } 22 | 23 | // get the matrix elements from user 24 | std::cout << std::endl << "Enter value of the matrix: " << std::endl; 25 | for (i = 0; i < mat_size; i++) { 26 | for (j = 0; j <= mat_size; j++) { 27 | std::cin >> 28 | mat[i][j]; // Enter (mat_size*mat_size) value of the matrix. 29 | } 30 | } 31 | 32 | // perform Gaussian elimination 33 | for (step = 0; step < mat_size - 1; step++) { 34 | for (i = step; i < mat_size - 1; i++) { 35 | double a = (mat[i + 1][step] / mat[step][step]); 36 | 37 | for (j = step; j <= mat_size; j++) 38 | mat[i + 1][j] = mat[i + 1][j] - (a * mat[step][j]); 39 | } 40 | } 41 | 42 | std::cout << std::endl 43 | << "Matrix using Gaussian Elimination method: " << std::endl; 44 | for (i = 0; i < mat_size; i++) { 45 | for (j = 0; j <= mat_size; j++) { 46 | x[i][j] = mat[i][j]; 47 | std::cout << mat[i][j] << " "; 48 | } 49 | std::cout << std::endl; 50 | } 51 | std::cout << std::endl 52 | << "Value of the Gaussian Elimination method: " << std::endl; 53 | for (i = mat_size - 1; i >= 0; i--) { 54 | double sum = 0; 55 | for (j = mat_size - 1; j > i; j--) { 56 | x[i][j] = x[j][j] * x[i][j]; 57 | sum = x[i][j] + sum; 58 | } 59 | if (x[i][i] == 0) 60 | x[i][i] = 0; 61 | else 62 | x[i][i] = (x[i][mat_size] - sum) / (x[i][i]); 63 | 64 | std::cout << "x" << i << "= " << x[i][i] << std::endl; 65 | } 66 | 67 | for (i = 0; i <= mat_size; i++) { 68 | delete[] mat[i]; 69 | if (i < mat_size) 70 | delete[] x[i]; 71 | } 72 | delete[] mat; 73 | delete[] x; 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /numerical_methods/newton_raphson_method.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * \brief Solve the equation \f$f(x)=0\f$ using [Newton-Raphson 4 | * method](https://en.wikipedia.org/wiki/Newton%27s_method) for both real and 5 | * complex solutions 6 | * 7 | * The \f$(i+1)^\text{th}\f$ approximation is given by: 8 | * \f[ 9 | * x_{i+1} = x_i - \frac{f(x_i)}{f'(x_i)} 10 | * \f] 11 | * 12 | * \author [Krishna Vedala](https://github.com/kvedala) 13 | * \see bisection_method.cpp, false_position.cpp 14 | */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | constexpr double EPSILON = 1e-10; ///< system accuracy limit 22 | constexpr int16_t MAX_ITERATIONS = INT16_MAX; ///< Maximum number of iterations 23 | 24 | /** define \f$f(x)\f$ to find root for. 25 | * Currently defined as: 26 | * \f[ 27 | * f(x) = x^3 - 4x - 9 28 | * \f] 29 | */ 30 | static double eq(double i) { 31 | return (std::pow(i, 3) - (4 * i) - 9); // original equation 32 | } 33 | 34 | /** define the derivative function \f$f'(x)\f$ 35 | * For the current problem, it is: 36 | * \f[ 37 | * f'(x) = 3x^2 - 4 38 | * \f] 39 | */ 40 | static double eq_der(double i) { 41 | return ((3 * std::pow(i, 2)) - 4); // derivative of equation 42 | } 43 | 44 | /** Main function */ 45 | int main() { 46 | std::srand(std::time(nullptr)); // initialize randomizer 47 | 48 | double z = NAN, c = std::rand() % 100, m = NAN, n = NAN; 49 | int i = 0; 50 | 51 | std::cout << "\nInitial approximation: " << c; 52 | 53 | // start iterations 54 | for (i = 0; i < MAX_ITERATIONS; i++) { 55 | m = eq(c); 56 | n = eq_der(c); 57 | 58 | z = c - (m / n); 59 | c = z; 60 | 61 | if (std::abs(m) < EPSILON) { // stoping criteria 62 | break; 63 | } 64 | } 65 | 66 | std::cout << "\n\nRoot: " << z << "\t\tSteps: " << i << std::endl; 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /numerical_methods/qr_decomposition.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * \brief Program to compute the [QR 4 | * decomposition](https://en.wikipedia.org/wiki/QR_decomposition) of a given 5 | * matrix. 6 | * \author [Krishna Vedala](https://github.com/kvedala) 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "./qr_decompose.h" 16 | 17 | using qr_algorithm::qr_decompose; 18 | using qr_algorithm::operator<<; 19 | 20 | /** 21 | * main function 22 | */ 23 | int main(void) { 24 | unsigned int ROWS, COLUMNS; 25 | 26 | std::cout << "Enter the number of rows and columns: "; 27 | std::cin >> ROWS >> COLUMNS; 28 | 29 | std::cout << "Enter matrix elements row-wise:\n"; 30 | 31 | std::valarray> A(ROWS); 32 | std::valarray> Q(ROWS); 33 | std::valarray> R(COLUMNS); 34 | for (int i = 0; i < std::max(ROWS, COLUMNS); i++) { 35 | if (i < ROWS) { 36 | A[i] = std::valarray(COLUMNS); 37 | Q[i] = std::valarray(COLUMNS); 38 | } 39 | if (i < COLUMNS) { 40 | R[i] = std::valarray(COLUMNS); 41 | } 42 | } 43 | 44 | for (int i = 0; i < ROWS; i++) 45 | for (int j = 0; j < COLUMNS; j++) std::cin >> A[i][j]; 46 | 47 | std::cout << A << "\n"; 48 | 49 | clock_t t1 = clock(); 50 | qr_decompose(A, &Q, &R); 51 | double dtime = static_cast(clock() - t1) / CLOCKS_PER_SEC; 52 | 53 | std::cout << Q << "\n"; 54 | std::cout << R << "\n"; 55 | std::cout << "Time taken to compute: " << dtime << " sec\n "; 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /numerical_methods/successive_approximation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * \brief Method of successive approximations using [fixed-point 4 | * iteration](https://en.wikipedia.org/wiki/Fixed-point_iteration) method 5 | */ 6 | #include 7 | #include 8 | 9 | /** equation 1 10 | * \f[f(y) = 3y - \cos y -2\f] 11 | */ 12 | static float eq(float y) { return (3 * y) - cos(y) - 2; } 13 | 14 | /** equation 2 15 | * \f[f(y) = \frac{\cos y+2}{2}\f] 16 | */ 17 | static float eqd(float y) { return 0.5 * (cos(y) + 2); } 18 | 19 | /** Main function */ 20 | int main() { 21 | float y, x1, x2, x3, sum, s, a, f1, f2, gd; 22 | int i, n; 23 | 24 | for (i = 0; i < 10; i++) { 25 | sum = eq(y); 26 | std::cout << "value of equation at " << i << " " << sum << "\n"; 27 | y++; 28 | } 29 | std::cout << "enter the x1->"; 30 | std::cin >> x1; 31 | std::cout << "enter the no iteration to perform->\n"; 32 | std::cin >> n; 33 | 34 | for (i = 0; i <= n; i++) { 35 | x2 = eqd(x1); 36 | std::cout << "\nenter the x2->" << x2; 37 | x1 = x2; 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /operations_on_datastructures/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | install(TARGETS ${testname} DESTINATION "bin/operations_on_datastructures") 14 | 15 | endforeach( testsourcefile ${APP_SOURCES} ) 16 | -------------------------------------------------------------------------------- /operations_on_datastructures/circular_queue_using_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cin; 3 | using std::cout; 4 | 5 | int queue[10]; 6 | int front = 0; 7 | int rear = 0; 8 | int count = 0; 9 | 10 | void Enque(int x) { 11 | if (count == 10) { 12 | cout << "\nOverflow"; 13 | } else { 14 | queue[rear] = x; 15 | rear = (rear + 1) % 10; 16 | count++; 17 | } 18 | } 19 | 20 | void Deque() { 21 | if (front == rear) { 22 | cout << "\nUnderflow"; 23 | } 24 | 25 | else { 26 | cout << "\n" << queue[front] << " deleted"; 27 | front = (front + 1) % 10; 28 | count--; 29 | } 30 | } 31 | 32 | void show() { 33 | for (int i = 0; i < count; i++) { 34 | cout << queue[(i + front) % 10] << "\t"; 35 | } 36 | } 37 | 38 | int main() { 39 | int ch, x; 40 | do { 41 | cout << "\n1. Enque"; 42 | cout << "\n2. Deque"; 43 | cout << "\n3. Print"; 44 | cout << "\nEnter Your Choice : "; 45 | cin >> ch; 46 | if (ch == 1) { 47 | cout << "\nInsert : "; 48 | cin >> x; 49 | Enque(x); 50 | } else if (ch == 2) { 51 | Deque(); 52 | } else if (ch == 3) { 53 | show(); 54 | } 55 | } while (ch != 0); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /operations_on_datastructures/get_size_of_linked_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Node { 4 | public: 5 | int val; 6 | Node *next; 7 | 8 | Node(int v, Node *n) : val(v), next(n) {} // Default constructor for Node 9 | }; 10 | 11 | int getSize(Node *root) { 12 | if (root == NULL) { 13 | return 0; 14 | } 15 | // Each node will return 1 so the total adds up to be the size 16 | return 1 + getSize(root->next); 17 | } 18 | 19 | /* 20 | * @brief This function dealocates memory related to the given list 21 | * It recursively deletes all of the nodes of the input list. 22 | * @param room the root/head of the input list 23 | * @warning Plese note that the memory for each node has to be alocated using new. 24 | */ 25 | void deleteList(Node *const root) { 26 | if (root != NULL) 27 | { 28 | deleteList(root->next); 29 | delete root; 30 | } 31 | } 32 | 33 | int main() { 34 | Node *myList = new Node(0, NULL); // Initializes the LinkedList 35 | Node *temp = myList; 36 | // Creates a linked lists of total size 10, numbered 1 - 10 37 | for (int i = 1; i < 10; i++) { 38 | temp->next = new Node(i, NULL); 39 | temp = temp->next; 40 | } 41 | // Creating other lists for checking purposes 42 | Node *secondList = new Node(0, NULL); // List of size 1 43 | Node *thirdList = NULL; // List of size 0 44 | 45 | std::cout << getSize(myList) << std::endl 46 | << getSize(secondList) << std::endl 47 | << getSize(thirdList) << std::endl; 48 | deleteList(secondList); 49 | deleteList(myList); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /operations_on_datastructures/reverse_a_linked_list_using_recusion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct node { 5 | int val; 6 | node *next; 7 | }; 8 | 9 | node *start; 10 | 11 | void insert(int x) { 12 | node *t = start; 13 | if (start != NULL) { 14 | while (t->next != NULL) { 15 | t = t->next; 16 | } 17 | node *n = new node; 18 | t->next = n; 19 | n->val = x; 20 | n->next = NULL; 21 | } else { 22 | node *n = new node; 23 | n->val = x; 24 | n->next = NULL; 25 | start = n; 26 | } 27 | } 28 | 29 | void reverse(node *p, node *q) { 30 | if (q->next == NULL) { 31 | q->next = p; 32 | p->next = NULL; 33 | start = q; 34 | return; 35 | } else { 36 | reverse(q, q->next); 37 | q->next = p; 38 | p->next = NULL; 39 | } 40 | } 41 | 42 | void show() { 43 | node *t = start; 44 | while (t != NULL) { 45 | cout << t->val << "\t"; 46 | t = t->next; 47 | } 48 | } 49 | 50 | int main() { 51 | insert(1); 52 | insert(2); 53 | insert(3); 54 | insert(4); 55 | insert(5); 56 | insert(6); 57 | 58 | reverse(start, start->next); 59 | 60 | show(); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /others/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/others") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /others/buzz_number.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief A buzz number is a number that is either divisible by 7 or has last 4 | * digit as 7. 5 | */ 6 | #include 7 | 8 | /** main function */ 9 | int main() { 10 | int n, t; 11 | std::cin >> t; 12 | while (t--) { 13 | std::cin >> n; 14 | if ((n % 7 == 0) || (n % 10 == 7)) 15 | std::cout << n << " is a buzz number" << std::endl; 16 | else 17 | std::cout << n << " is not a buzz number" << std::endl; 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /others/decimal_to_binary.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Function to convert decimal number to binary representation 4 | */ 5 | #include 6 | 7 | /** 8 | * This method converts the bit representation and stores it as a decimal 9 | * number. 10 | */ 11 | void method1(int number) { 12 | int remainder, binary = 0, var = 1; 13 | 14 | do { 15 | remainder = number % 2; 16 | number = number / 2; 17 | binary = binary + (remainder * var); 18 | var = var * 10; 19 | } while (number > 0); 20 | std::cout << "Method 1 : " << binary << std::endl; 21 | } 22 | 23 | /** 24 | * This method stores each bit value from LSB to MSB and then prints them back 25 | * from MSB to LSB 26 | */ 27 | void method2(int number) { 28 | int num_bits = 0; 29 | char bit_string[50]; 30 | 31 | do { 32 | bool bit = number & 0x01; // get last bit 33 | if (bit) 34 | bit_string[num_bits++] = '1'; 35 | else 36 | bit_string[num_bits++] = '0'; 37 | number >>= 1; // right shift bit 1 bit 38 | } while (number > 0); 39 | 40 | std::cout << "Method 2 : "; 41 | while (num_bits >= 0) 42 | std::cout << bit_string[num_bits--]; // print from MSB to LSB 43 | std::cout << std::endl; 44 | } 45 | 46 | int main() { 47 | int number; 48 | std::cout << "Enter a number:"; 49 | std::cin >> number; 50 | 51 | method1(number); 52 | method2(number); 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /others/decimal_to_hexadecimal.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Convert decimal number to hexadecimal representation 4 | */ 5 | 6 | #include 7 | 8 | /** 9 | * Main program 10 | */ 11 | int main(void) { 12 | int valueToConvert = 0; // Holds user input 13 | int hexArray[8]; // Contains hex values backwards 14 | int i = 0; // counter 15 | char HexValues[] = "0123456789ABCDEF"; 16 | 17 | std::cout << "Enter a Decimal Value" 18 | << std::endl; // Displays request to stdout 19 | std::cin >> 20 | valueToConvert; // Stores value into valueToConvert via user input 21 | 22 | while (valueToConvert > 15) { // Dec to Hex Algorithm 23 | hexArray[i++] = valueToConvert % 16; // Gets remainder 24 | valueToConvert /= 16; 25 | // valueToConvert >>= 4; // This will divide by 2^4=16 and is faster 26 | } 27 | hexArray[i] = valueToConvert; // Gets last value 28 | 29 | std::cout << "Hex Value: "; 30 | while (i >= 0) std::cout << HexValues[hexArray[i--]]; 31 | 32 | std::cout << std::endl; 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /others/fast_integer_input.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Read integers from stdin continuously as they are entered without 4 | * waiting for the `\n` character 5 | */ 6 | #include 7 | 8 | /** Function to read the number from stdin. The function reads input until a non 9 | * numeric character is entered. 10 | */ 11 | void fastinput(int *number) { 12 | // variable to indicate sign of input integer 13 | bool negative = false; 14 | int c; 15 | *number = 0; 16 | 17 | // extract current character from buffer 18 | c = std::getchar(); 19 | if (c == '-') { 20 | // number is negative 21 | negative = true; 22 | 23 | // extract the next character from the buffer 24 | c = std::getchar(); 25 | } 26 | 27 | // Keep on extracting characters if they are integers 28 | // i.e ASCII Value lies from '0'(48) to '9' (57) 29 | for (; (c > 47 && c < 58); c = std::getchar()) 30 | *number = *number * 10 + c - 48; 31 | 32 | // if scanned input has a negative sign, negate the 33 | // value of the input number 34 | if (negative) 35 | *(number) *= -1; 36 | } 37 | 38 | /** Main function */ 39 | int main() { 40 | int number; 41 | fastinput(&number); 42 | std::cout << number << std::endl; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /others/happy_number.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief A happy number is a number whose sum of digits is calculated until the 4 | * sum is a single digit, and this sum turns out to be 1 5 | */ 6 | 7 | #include 8 | 9 | /** 10 | * Checks if a decimal number is a happy number 11 | * \returns true if happy else false 12 | */ 13 | template 14 | bool is_happy(T n) { 15 | T s = 0; // stores sum of digits 16 | while (n > 9) { // while number is > 9, there are more than 1 digit 17 | while (n != 0) { // get digit 18 | T d = n % 10; 19 | s += d; 20 | n /= 10; 21 | } 22 | n = s; 23 | s = 0; 24 | } 25 | return (n == 1) ? true : false; // true if k == 1 26 | } 27 | 28 | /** Main function */ 29 | int main() { 30 | int n; 31 | std::cout << "Enter a number:"; 32 | std::cin >> n; 33 | 34 | if (is_happy(n)) 35 | std::cout << n << " is a happy number" << std::endl; 36 | else 37 | std::cout << n << " is not a happy number" << std::endl; 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /others/palindrome_of_number.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Check if a number is 4 | * [palindrome](https://en.wikipedia.org/wiki/Palindrome) or not. 5 | * 6 | * This program cheats by using the STL library's std::reverse function. 7 | */ 8 | #include 9 | #include 10 | 11 | #ifdef _MSC_VER 12 | // Required to compile std::toString function using MSVC 13 | #include 14 | #else 15 | #include 16 | #endif 17 | 18 | /** Main function */ 19 | int main() { 20 | int num; 21 | std::cout << "Enter number = "; 22 | std::cin >> num; 23 | 24 | std::string s1 = std::to_string(num); // convert number to string 25 | std::string s2 = s1; 26 | 27 | std::reverse(s1.begin(), s1.end()); // reverse the string 28 | 29 | if (s1 == s2) // check if reverse and original string are identical 30 | std::cout << "true"; 31 | else 32 | std::cout << "false"; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /others/paranthesis_matching.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Perform paranthesis matching. \note Do not know the application of 4 | * this, however. 5 | * @note Implementation is C-type and does not utilize the C++ constructs 6 | * @todo implement as a C++ class 7 | */ 8 | #include 9 | #ifdef _MSC_VER 10 | #include // Visual Studio C requires this include 11 | #else 12 | #include 13 | #endif 14 | 15 | /** check number */ 16 | #define MAX 100 17 | 18 | //! @{-------------- stack -------------- 19 | //! global stack 20 | char stack[MAX]; 21 | 22 | //! pointer to track stack index 23 | int stack_idx = -1; 24 | 25 | //! push byte to stack variable 26 | void push(char ch) { stack[++stack_idx] = ch; } 27 | 28 | //! pop a byte out of stack variable 29 | char pop() { return stack[stack_idx--]; } 30 | 31 | //! @}-------------- end stack ----------- 32 | 33 | /** return opening paranthesis corresponding to the close paranthesis 34 | * @param[in] ch closed paranthesis character 35 | */ 36 | char opening(char ch) { 37 | switch (ch) { 38 | case '}': 39 | return '{'; 40 | case ']': 41 | return '['; 42 | case ')': 43 | return '('; 44 | case '>': 45 | return '<'; 46 | } 47 | return '\0'; 48 | } 49 | 50 | int main() { 51 | std::string exp; 52 | int valid = 1, i = 0; 53 | std::cout << "Enter The Expression : "; 54 | std::cin >> exp; 55 | 56 | while (valid == 1 && i < exp.length()) { 57 | if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[' || exp[i] == '<') { 58 | push(exp[i]); 59 | } else if (stack_idx >= 0 && stack[stack_idx] == opening(exp[i])) { 60 | pop(); 61 | } else { 62 | valid = 0; 63 | } 64 | i++; 65 | } 66 | 67 | // makes sure the stack is empty after processsing (above) 68 | if (valid == 1 && stack_idx == -1) { 69 | std::cout << "\nCorrect Expression"; 70 | } else { 71 | std::cout << "\nWrong Expression"; 72 | } 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /others/pascal_triangle.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Pascal's triangle implementation 4 | */ 5 | #ifdef _MSC_VER 6 | #include // required for Visual C 7 | #else 8 | #include 9 | #endif 10 | #include 11 | #include 12 | 13 | /** 14 | * Print the triangle 15 | * \param [in] arr 2D-array containing Pascal numbers 16 | * \param [in] n depth of Pascal triangle to print 17 | */ 18 | void show_pascal(int **arr, int n) { 19 | for (int i = 0; i < n; ++i) { 20 | for (int j = 0; j < n + i; ++j) { 21 | if (arr[i][j] == 0) 22 | std::cout << std::setw(4) << " "; 23 | else 24 | std::cout << std::setw(4) << arr[i][j]; 25 | } 26 | std::cout << std::endl; 27 | } 28 | } 29 | 30 | /** 31 | * Print the triangle 32 | * \param [in,out] arr array containing Pascal numbers 33 | * \param [in] n depth of Pascal triangle to print 34 | * \result arr pointer returned 35 | */ 36 | int **pascal_triangle(int **arr, int n) { 37 | for (int i = 0; i < n; ++i) { 38 | for (int j = n - i - 1; j < n + i; ++j) { 39 | if (j == n - i - 1 || j == n + i - 1) 40 | arr[i][j] = 1; // The edge of the Pascal triangle goes in 1 41 | else 42 | arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j + 1]; 43 | } 44 | } 45 | 46 | return arr; 47 | } 48 | 49 | /** 50 | * main function 51 | */ 52 | int main() { 53 | int n = 0; 54 | 55 | std::cout << "Set Pascal's Triangle Height" << std::endl; 56 | std::cin >> n; 57 | 58 | // memory allocation (Assign two-dimensional array to store Pascal triangle) 59 | int **arr = new int *[n]; 60 | for (int i = 0; i < n; ++i) { 61 | arr[i] = new int[2 * n - 1]; 62 | memset(arr[i], 0, sizeof(int) * (2 * n - 1)); 63 | } 64 | 65 | pascal_triangle(arr, n); 66 | show_pascal(arr, n); 67 | 68 | // deallocation 69 | for (int i = 0; i < n; ++i) { 70 | delete[] arr[i]; 71 | } 72 | delete[] arr; 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /others/primality_test.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief [Primality test](https://en.wikipedia.org/wiki/Primality_test) 4 | * implementation. 5 | * 6 | * A simple and efficient implementation of a function to test if a number is 7 | * prime, based on the fact that 8 | * > Every Prime number, except 2 and 3, are of the form \f$6k\pm1\f$ for 9 | * > integer values of k. 10 | * This gives a 3x speed improvement. 11 | */ 12 | #include 13 | 14 | /** Check if a number is prime 15 | * \param[in] number number to check 16 | * \returns true if prime else false 17 | */ 18 | bool IsPrime(int number) { 19 | if (((!(number & 1)) && number != 2) || (number < 2) || 20 | (number % 3 == 0 && number != 3)) 21 | return false; 22 | 23 | for (int k = 1; 36 * k * k - 12 * k < number; ++k) { 24 | if ((number % (6 * k + 1) == 0) || (number % (6 * k - 1) == 0)) 25 | return false; 26 | } 27 | return true; 28 | } 29 | 30 | /** main function */ 31 | int main() { 32 | // Main Function 33 | std::cout << "Enter the value of n to check if Prime\n"; 34 | int n; 35 | std::cin >> n; 36 | if (IsPrime(n)) 37 | std::cout << n << " is Prime" << std::endl; 38 | else 39 | std::cout << n << " is not Prime" << std::endl; 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /others/sparse_matrix.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | * A sparse matrix is a matrix which has number of zeroes greater than 3 | * \f$\frac{m\times n}{2}\f$, where m and n are the dimensions of the matrix. 4 | */ 5 | 6 | #include 7 | 8 | /** main function */ 9 | int main() { 10 | int m, n; 11 | int counterZeros = 0; 12 | 13 | std::cout << "Enter dimensions of matrix (seperated with space): "; 14 | std::cin >> m; 15 | std::cin >> n; 16 | 17 | int **a = new int *[m]; 18 | for (int i = 0; i < m; i++) a[i] = new int[n]; 19 | 20 | std::cout << "Enter matrix elements:"; 21 | std::cout << "\n"; 22 | 23 | // reads the matrix from stdin 24 | for (int i = 0; i < m; i++) { 25 | for (int j = 0; j < n; j++) { 26 | std::cout << "element? "; 27 | std::cin >> a[i][j]; 28 | } 29 | } 30 | 31 | // counts the zero's 32 | for (int i = 0; i < m; i++) { 33 | for (int j = 0; j < n; j++) { 34 | if (a[i][j] == 0) 35 | counterZeros++; // Counting number of zeroes 36 | } 37 | } 38 | 39 | // makes sure the matrix is a sparse matrix 40 | if (counterZeros > ((m * n) / 2)) // Checking for sparse matrix 41 | std::cout << "Sparse matrix"; 42 | else 43 | std::cout << "Not a sparse matrix"; 44 | 45 | for (int i = 0; i < m; i++) delete[] a[i]; 46 | delete[] a; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /others/spiral_print.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Print the elements of a matrix traversing it spirally 4 | */ 5 | #include 6 | 7 | /** Arrange sequence of numbers from '1' in a matrix form 8 | * \param [out] a matrix to fill 9 | * \param [in] r number of rows 10 | * \param [in] c number of columns 11 | */ 12 | void genArray(int **a, int r, int c) { 13 | int value = 1; 14 | for (int i = 0; i < r; i++) { 15 | for (int j = 0; j < c; j++) { 16 | a[i][j] = value; 17 | std::cout << a[i][j] << " "; 18 | value++; 19 | } 20 | std::cout << std::endl; 21 | } 22 | } 23 | 24 | /** Traverse the matrix spirally and print the sequence of elements 25 | * \param [in] a matrix to read from 26 | * \param [in] r number of rows 27 | * \param [in] c number of columns 28 | */ 29 | void spiralPrint(int **a, int r, int c) { 30 | int startRow = 0, endRow = r - 1; 31 | int startCol = 0, endCol = c - 1; 32 | int cnt = 0; 33 | 34 | while (startRow <= endRow && startCol <= endCol) { 35 | /// Print start row 36 | for (int i = startCol; i <= endCol; i++, cnt++) { 37 | std::cout << a[startRow][i] << " "; 38 | } 39 | startRow++; 40 | 41 | /// Print the end col 42 | for (int i = startRow; i <= endRow; i++, cnt++) { 43 | std::cout << a[i][endCol] << " "; 44 | } 45 | endCol--; 46 | 47 | /// Print the end row 48 | if (cnt == r * c) { 49 | break; 50 | } 51 | 52 | for (int i = endCol; i >= startCol; i--, cnt++) { 53 | std::cout << a[endRow][i] << " "; 54 | } 55 | endRow--; 56 | 57 | /// Print the start Col 58 | if (cnt == r * c) { 59 | break; 60 | } 61 | for (int i = endRow; i >= startRow; i--, cnt++) { 62 | std::cout << a[i][startCol] << " "; 63 | } 64 | startCol++; 65 | } 66 | } 67 | 68 | /** main function */ 69 | int main() { 70 | int r, c; 71 | std::cin >> r >> c; 72 | int **a = new int *[r]; 73 | for (int i = 0; i < r; i++) a[i] = new int[c]; 74 | 75 | genArray(a, r, c); 76 | spiralPrint(a, r, c); 77 | 78 | for (int i = 0; i < r; i++) delete[] a[i]; 79 | delete[] a; 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /others/stairs_pattern.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | @brief This program is use to print the following pattern
 4 |    \*\*
 5 |    \*\*
 6 |   \*\*\*\*
 7 |   \*\*\*\*
 8 |  \*\*\*\*\*\*
 9 |  \*\*\*\*\*\*
10 | \*\*\*\*\*\*\*\*
11 | ********
12 | where number of pairs line is given by user 13 | */ 14 | #include 15 | 16 | /** main function */ 17 | int main() { 18 | int l, st = 2, x, r, z, n, sp; 19 | std::cout << "Enter number of pair - "; 20 | std::cin >> x; 21 | z = x; 22 | for (r = 1; r <= x; r++) { 23 | z = z - 1; 24 | for (n = 1; n <= 2; n++) { 25 | for (sp = 1; sp <= z; sp++) { 26 | std::cout << " "; 27 | } 28 | for (l = 1; l <= st; l++) { 29 | std::cout << "\\*"; 30 | } 31 | std::cout << std::endl; 32 | } 33 | st = st + 2; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /others/tower_of_hanoi.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Solve the [Tower of 4 | * Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi) problem. 5 | */ 6 | #include 7 | 8 | /** 9 | * Define the state of tower 10 | */ 11 | struct tower { 12 | //! Values in the tower 13 | int values[10]; 14 | //! top tower ID 15 | int top; 16 | }; 17 | 18 | /** Display the towers */ 19 | void show(const struct tower *const F, const struct tower *const T, 20 | const struct tower *const U) { 21 | std::cout << "\n\n\tF : "; 22 | for (int i = 0; i < F->top; i++) { 23 | std::cout << F->values[i] << "\t"; 24 | } 25 | std::cout << "\n\tU : "; 26 | for (int i = 0; i < U->top; i++) { 27 | std::cout << U->values[i] << "\t"; 28 | } 29 | std::cout << "\n\tT : "; 30 | for (int i = 0; i < T->top; i++) { 31 | std::cout << T->values[i] << "\t"; 32 | } 33 | } 34 | 35 | /** Move one disc from one tower to another 36 | * \param [in,out] From tower to move disk *from* 37 | * \param [in,out] To tower to move disk *to* 38 | */ 39 | void mov(tower *From, tower *To) { 40 | --From->top; 41 | To->values[To->top] = From->values[From->top]; 42 | ++To->top; 43 | } 44 | 45 | /** 46 | * Recursive algorithm to solve the puzzle 47 | * \param [in] n starting number of disks 48 | * \param [in,out] From tower to move disks from 49 | * \param [in,out] Using temporary tower for the puzzle 50 | * \param [in,out] To tower to move disk to 51 | */ 52 | void TH(int n, tower *From, tower *Using, tower *To) { 53 | if (n == 1) { 54 | mov(From, To); 55 | show(From, To, Using); 56 | } else { 57 | TH(n - 1, From, To, Using); 58 | mov(From, To); 59 | show(From, To, Using); 60 | TH(n - 1, Using, From, To); 61 | } 62 | } 63 | 64 | /** Main function */ 65 | int main() { 66 | struct tower F, U, T; 67 | 68 | F.top = 0; 69 | U.top = 0; 70 | T.top = 0; 71 | 72 | int no; 73 | 74 | std::cout << "\nEnter number of discs : "; 75 | std::cin >> no; 76 | 77 | for (int i = no; i > 0; i--) { 78 | F.values[F.top++] = i; 79 | } 80 | 81 | show(&F, &T, &U); 82 | TH(no, &F, &U, &T); 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /others/vector_important_functions.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief A C++ program to demonstrate working of std::sort(), std::reverse() 4 | */ 5 | #include 6 | #include 7 | #include // For accumulate operation 8 | #include 9 | 10 | /** Main function */ 11 | int main() { 12 | // Initializing vector with array values 13 | int arr[] = {10, 20, 5, 23, 42, 15}; 14 | int n = sizeof(arr) / sizeof(arr[0]); 15 | std::vector vect(arr, arr + n); 16 | 17 | std::cout << "Vector is: "; 18 | for (int i = 0; i < n; i++) std::cout << vect[i] << " "; 19 | 20 | // Sorting the Vector in Ascending order 21 | std::sort(vect.begin(), vect.end()); 22 | 23 | std::cout << "\nVector after sorting is: "; 24 | for (int i = 0; i < n; i++) std::cout << vect[i] << " "; 25 | 26 | // Reversing the Vector 27 | std::reverse(vect.begin(), vect.end()); 28 | 29 | std::cout << "\nVector after reversing is: "; 30 | for (int i = 0; i < 6; i++) std::cout << vect[i] << " "; 31 | 32 | std::cout << "\nMaximum element of vector is: "; 33 | std::cout << *max_element(vect.begin(), vect.end()); 34 | 35 | std::cout << "\nMinimum element of vector is: "; 36 | std::cout << *min_element(vect.begin(), vect.end()); 37 | 38 | // Starting the summation from 0 39 | std::cout << "\nThe summation of vector elements is: "; 40 | std::cout << accumulate(vect.begin(), vect.end(), 0); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /physics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. The RELATIVE flag makes it easier to extract an executable's name 3 | # automatically. 4 | 5 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 6 | foreach( testsourcefile ${APP_SOURCES} ) 7 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) # File type. Example: `.cpp` 8 | add_executable( ${testname} ${testsourcefile} ) 9 | 10 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 11 | if(OpenMP_CXX_FOUND) 12 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 13 | endif() 14 | install(TARGETS ${testname} DESTINATION "bin/physics") # Folder name. Do NOT include `<>` 15 | 16 | endforeach( testsourcefile ${APP_SOURCES} ) 17 | -------------------------------------------------------------------------------- /probability/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/probability") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /probability/addition_rule.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Addition rule of probabilities 4 | */ 5 | #include 6 | 7 | /** 8 | * calculates the probability of the independent events A or B for independent 9 | * events 10 | * \parama [in] A probability of event A 11 | * \parama [in] B probability of event B 12 | * \returns probability of A and B 13 | */ 14 | double addition_rule_independent(double A, double B) { 15 | return (A + B) - (A * B); 16 | } 17 | 18 | /** Calculates the probability of the events A or B for dependent events 19 | * note that if value of B_given_A is unknown, use chainrule to find it 20 | * \parama [in] A probability of event A 21 | * \parama [in] B probability of event B 22 | * \parama [in] B_given_A probability of event B condition A 23 | * \returns probability of A and B 24 | */ 25 | double addition_rule_dependent(double A, double B, double B_given_A) { 26 | return (A + B) - (A * B_given_A); 27 | } 28 | 29 | /** Main function */ 30 | int main() { 31 | double A = 0.5; 32 | double B = 0.25; 33 | double B_given_A = 0.05; 34 | 35 | std::cout << "independent P(A or B) = " << addition_rule_independent(A, B) 36 | << std::endl; 37 | 38 | std::cout << "dependent P(A or B) = " 39 | << addition_rule_dependent(A, B, B_given_A) << std::endl; 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /probability/bayes_theorem.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief [Bayes' theorem](https://en.wikipedia.org/wiki/Bayes%27_theorem) 4 | * 5 | * Bayes' theorem allows one to find \f$P(A|B)\f$ given \f$P(B|A)\f$ or 6 | * \f$P(B|A)\f$ given \f$P(A|B)\f$ and \f$P(A)\f$ and \f$P(B)\f$.\n 7 | * Note that \f$P(A|B)\f$ is read 'The probability of A given that the event B 8 | * has occured'. 9 | */ 10 | #include 11 | 12 | /** returns P(A|B) 13 | */ 14 | double bayes_AgivenB(double BgivenA, double A, double B) { 15 | return (BgivenA * A) / B; 16 | } 17 | 18 | /** returns P(B|A) 19 | */ 20 | double bayes_BgivenA(double AgivenB, double A, double B) { 21 | return (AgivenB * B) / A; 22 | } 23 | 24 | /** Main function 25 | */ 26 | int main() { 27 | double A = 0.01; 28 | double B = 0.1; 29 | double BgivenA = 0.9; 30 | double AgivenB = bayes_AgivenB(BgivenA, A, B); 31 | std::cout << "A given B = " << AgivenB << std::endl; 32 | std::cout << "B given A = " << bayes_BgivenA(AgivenB, A, B) << std::endl; 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /probability/poisson_dist.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief [Poisson 4 | * statistics](https://en.wikipedia.org/wiki/Poisson_distribution) 5 | * 6 | * The Poisson distribution counts how many 7 | * events occur over a set time interval. 8 | */ 9 | #include 10 | #include 11 | 12 | /** 13 | * poisson rate:\n 14 | * calculate the events per unit time\n 15 | * e.g 5 dollars every 2 mins = 5 / 2 = 2.5 16 | */ 17 | double poisson_rate(double events, double timeframe) { 18 | return events / timeframe; 19 | } 20 | 21 | /** 22 | * calculate the expected value over a time 23 | * e.g rate of 2.5 over 10 mins = 2.5 x 10 = 25 24 | */ 25 | double poisson_expected(double rate, double time) { return rate * time; } 26 | 27 | /** 28 | * Compute factorial of a given number 29 | */ 30 | double fact(double x) { 31 | double x_fact = x; 32 | for (int i = x - 1; i > 0; i--) { 33 | x_fact *= i; 34 | } 35 | 36 | if (x_fact <= 0) { 37 | x_fact = 1; 38 | } 39 | return x_fact; 40 | } 41 | 42 | /** 43 | * Find the probability of x successes in a Poisson dist. 44 | * \f[p(\mu,x) = \frac{\mu^x e^{-\mu}}{x!}\f] 45 | */ 46 | double poisson_x_successes(double expected, double x) { 47 | return (std::pow(expected, x) * std::exp(-expected)) / fact(x); 48 | } 49 | 50 | /** 51 | * probability of a success in range for Poisson dist (inclusive, inclusive) 52 | * \f[P = \sum_i p(\mu,i)\f] 53 | */ 54 | double poisson_range_successes(double expected, double lower, double upper) { 55 | double probability = 0; 56 | for (int i = lower; i <= upper; i++) { 57 | probability += poisson_x_successes(expected, i); 58 | } 59 | return probability; 60 | } 61 | 62 | /** 63 | * main function 64 | */ 65 | int main() { 66 | double rate, expected; 67 | rate = poisson_rate(3, 1); 68 | std::cout << "Poisson rate : " << rate << std::endl; 69 | 70 | expected = poisson_expected(rate, 2); 71 | std::cout << "Poisson expected : " << expected << std::endl; 72 | 73 | std::cout << "Poisson 0 successes : " << poisson_x_successes(expected, 0) 74 | << std::endl; 75 | std::cout << "Poisson 0-8 successes : " 76 | << poisson_range_successes(expected, 0, 8) << std::endl; 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /range_queries/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/range_queries") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /range_queries/mo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int N = 1e6 + 5; 7 | int a[N], bucket[N], cnt[N]; 8 | int bucket_size; 9 | struct query { 10 | int l, r, i; 11 | } q[N]; 12 | int ans = 0; 13 | 14 | void add(int index) { 15 | cnt[a[index]]++; 16 | if (cnt[a[index]] == 1) 17 | ans++; 18 | } 19 | void remove(int index) { 20 | cnt[a[index]]--; 21 | if (cnt[a[index]] == 0) 22 | ans--; 23 | } 24 | 25 | bool mycmp(query x, query y) { 26 | if (x.l / bucket_size != y.l / bucket_size) 27 | return x.l / bucket_size < y.l / bucket_size; 28 | return x.r < y.r; 29 | } 30 | 31 | int main() { 32 | int n, t, i, j, k = 0; 33 | scanf("%d", &n); 34 | for (i = 0; i < n; i++) scanf("%d", &a[i]); 35 | bucket_size = ceil(sqrt(n)); 36 | scanf("%d", &t); 37 | for (i = 0; i < t; i++) { 38 | scanf("%d %d", &q[i].l, &q[i].r); 39 | q[i].l--; 40 | q[i].r--; 41 | q[i].i = i; 42 | } 43 | sort(q, q + t, mycmp); 44 | int left = 0, right = 0; 45 | for (i = 0; i < t; i++) { 46 | int L = q[i].l, R = q[i].r; 47 | while (left < L) { 48 | remove(left); 49 | left++; 50 | } 51 | while (left > L) { 52 | add(left - 1); 53 | left--; 54 | } 55 | while (right <= R) { 56 | add(right); 57 | right++; 58 | } 59 | while (right > R + 1) { 60 | remove(right - 1); 61 | right--; 62 | } 63 | bucket[q[i].i] = ans; 64 | } 65 | for (i = 0; i < t; i++) printf("%d\n", bucket[i]); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /range_queries/prefix_sum_array.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief 4 | * [Prefix Sum 5 | * Array](https://en.wikipedia.org/wiki/Prefix_sum) data structure 6 | * implementation. 7 | * 8 | * @details 9 | * Prefix Sum Array is a data structure, that allows answering sum in some range 10 | * queries. It can answer most sum range queries in O(1), with a build time 11 | * complexity of O(N). But it hasn't an update querie. 12 | * 13 | * * Running Time Complexity \n 14 | * * Build : O(N) \n 15 | * * Range Query : O(1) \n 16 | * @author [Paulo Vitor Lima Borges](https://github.com/PauloVLB) 17 | */ 18 | 19 | #include /// for assert 20 | #include /// for IO operations 21 | #include /// for std::vector 22 | 23 | /** 24 | * @namespace range_queries 25 | * @brief Range Queries algorithms 26 | */ 27 | namespace range_queries { 28 | /** 29 | * @namespace prefix_sum_array 30 | * @brief Range sum queries using prefix-sum-array 31 | */ 32 | namespace prefix_sum_array { 33 | 34 | std::vector PSA(1, 0); 35 | 36 | /** 37 | * @brief function that builds the PSA 38 | * @param original_array original array of values 39 | * @returns void 40 | */ 41 | void build(std::vector original_array) { 42 | for (int i = 1; i <= static_cast(original_array.size()); i++) { 43 | PSA.push_back(PSA[i - 1] + original_array[i]); 44 | } 45 | } 46 | /** 47 | * @brief query function 48 | * @param beg begin of the interval to sum 49 | * @param end end of the interval to sum 50 | * @returns sum of the range [beg, end] 51 | */ 52 | int64_t query(int64_t beg, int64_t end) { return PSA[end] - PSA[beg - 1]; } 53 | 54 | } // namespace prefix_sum_array 55 | } // namespace range_queries 56 | 57 | /** 58 | * @brief Self-test implementations 59 | * @returns void 60 | */ 61 | static void test() { 62 | std::vector values{0, 123, 0, 2, -2, 5, 63 | 24, 0, 23, -1, -1}; // original array 64 | 65 | range_queries::prefix_sum_array::build(values); 66 | // queries are of the type: sum of the range [a, b] = psa[b] - psa[a-1] 67 | 68 | assert(range_queries::prefix_sum_array::query(1, 10) == 69 | 173); // sum of the entire array 70 | assert(range_queries::prefix_sum_array::query(4, 6) == 71 | 27); // the sum of the interval [4, 6] 72 | assert(range_queries::prefix_sum_array::query(5, 9) == 73 | 51); // the sum of the interval [5, 9] 74 | } 75 | 76 | /** 77 | * @brief Main function 78 | * @returns 0 on exit 79 | */ 80 | int main() { 81 | test(); // run self-test implementations 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /scripts/file_linter.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import sys 4 | 5 | print("Python {}.{}.{}".format(*sys.version_info)) # Python 3.8 6 | with open("git_diff.txt") as in_file: 7 | modified_files = sorted(in_file.read().splitlines()) 8 | print("{} files were modified.".format(len(modified_files))) 9 | 10 | cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split()) 11 | cpp_files = [file for file in modified_files if file.lower().endswith(cpp_exts)] 12 | print(f"{len(cpp_files)} C++ files were modified.") 13 | if not cpp_files: 14 | sys.exit(0) 15 | 16 | subprocess.run(["clang-tidy", "--fix", "-p=build", "--extra-arg=-std=c++11", *cpp_files, "--"], 17 | check=True, text=True, stderr=subprocess.STDOUT) 18 | 19 | subprocess.run(["clang-format", "-i", "-style=file", *cpp_files], 20 | check=True, text=True, stderr=subprocess.STDOUT) 21 | 22 | upper_files = [file for file in cpp_files if file != file.lower()] 23 | if upper_files: 24 | print(f"{len(upper_files)} files contain uppercase characters:") 25 | print("\n".join(upper_files) + "\n") 26 | 27 | space_files = [file for file in cpp_files if " " in file or "-" in file] 28 | if space_files: 29 | print(f"{len(space_files)} files contain space or dash characters:") 30 | print("\n".join(space_files) + "\n") 31 | 32 | nodir_files = [file for file in cpp_files if file.count(os.sep) != 1] 33 | if nodir_files: 34 | print(f"{len(nodir_files)} files are not in one and only one directory:") 35 | print("\n".join(nodir_files) + "\n") 36 | 37 | bad_files = len(upper_files + space_files + nodir_files) 38 | if bad_files: 39 | sys.exit(bad_files) 40 | -------------------------------------------------------------------------------- /search/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/search") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /search/interpolation_search2.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * \brief [Interpolation 4 | * search](https://en.wikipedia.org/wiki/Interpolation_search) algorithm 5 | */ 6 | #include 7 | 8 | /** function to search the value in an array using interpolation search 9 | * \param [in] arr array to search in 10 | * \param [in] value value to search for 11 | * \param [in] len length of array 12 | * \returns index where the value is found 13 | * \returns -1 if not found 14 | */ 15 | int InterpolationSearch(int A[], int n, int x) { 16 | int low = 0; 17 | int high = n - 1; 18 | while (low <= high) { 19 | int mid = low + (((high - 1) * (x - A[low])) / (A[high] - A[low])); 20 | if (x == A[mid]) 21 | return mid; // Found x, return (exit) 22 | else if (x < A[mid]) 23 | high = mid - 1; // X lies before mid 24 | else 25 | low = mid + 1; // x lies after mid 26 | } 27 | 28 | return -1; 29 | } 30 | 31 | /** main function */ 32 | int main() { 33 | int A[] = {2, 4, 5, 7, 13, 14, 15, 23}; 34 | int x = 17; 35 | 36 | ///< passed array A inside the InterpolationSearch function 37 | int index = InterpolationSearch(A, 8, x); 38 | if (index < 0) 39 | std::cout << "Number " << x << " not found" << std::endl; 40 | else 41 | std::cout << "Number " << x << " is at " << index << std::endl; 42 | } 43 | 44 | // randomly set x bcoz array was defined by us , therefore not reasonable for 45 | // asking input. We could have asked for input if array elements were inputed by 46 | // the user. 47 | -------------------------------------------------------------------------------- /search/jump_search.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * \brief C++ program to implement [Jump 4 | * Search](https://en.wikipedia.org/wiki/Jump_search) 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | /** jump search implementation 11 | */ 12 | int jumpSearch(int arr[], int x, int n) { 13 | // Finding block size to be jumped 14 | int step = std::sqrt(n); 15 | 16 | // Finding the block where element is 17 | // present (if it is present) 18 | int prev = 0; 19 | while (arr[std::min(step, n) - 1] < x) { 20 | prev = step; 21 | step += std::sqrt(n); 22 | if (prev >= n) 23 | return -1; 24 | } 25 | 26 | // Doing a linear search for x in block 27 | // beginning with prev. 28 | while (arr[prev] < x) { 29 | prev++; 30 | 31 | // If we reached next block or end of 32 | // array, element is not present. 33 | if (prev == std::min(step, n)) 34 | return -1; 35 | } 36 | // If element is found 37 | if (arr[prev] == x) 38 | return prev; 39 | 40 | return -1; 41 | } 42 | 43 | // Driver program to test function 44 | int main() { 45 | int arr[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610}; 46 | int x = 55; 47 | int n = sizeof(arr) / sizeof(arr[0]); 48 | 49 | // Find the index of 'x' using Jump Search 50 | int index = jumpSearch(arr, x, n); 51 | 52 | // Print the index where 'x' is located 53 | std::cout << "\nNumber " << x << " is at index " << index; 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /sorting/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES 13 | LINKER_LANGUAGE CXX 14 | CXX_STANDARD 14) 15 | if(OpenMP_CXX_FOUND) 16 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 17 | endif() 18 | install(TARGETS ${testname} DESTINATION "bin/sorting") 19 | 20 | endforeach( testsourcefile ${APP_SOURCES} ) 21 | -------------------------------------------------------------------------------- /sorting/bead_sort.cpp: -------------------------------------------------------------------------------- 1 | // C++ program to implement gravity/bead sort 2 | #include 3 | #include 4 | 5 | #define BEAD(i, j) beads[i * max + j] 6 | 7 | // function to perform the above algorithm 8 | void beadSort(int *a, int len) { 9 | // Find the maximum element 10 | int max = a[0]; 11 | for (int i = 1; i < len; i++) 12 | if (a[i] > max) 13 | max = a[i]; 14 | 15 | // allocating memory 16 | unsigned char *beads = new unsigned char[max * len]; 17 | memset(beads, 0, static_cast(max) * len); 18 | 19 | // mark the beads 20 | for (int i = 0; i < len; i++) 21 | for (int j = 0; j < a[i]; j++) BEAD(i, j) = 1; 22 | 23 | for (int j = 0; j < max; j++) { 24 | // count how many beads are on each post 25 | int sum = 0; 26 | for (int i = 0; i < len; i++) { 27 | sum += BEAD(i, j); 28 | BEAD(i, j) = 0; 29 | } 30 | 31 | // Move beads down 32 | for (int i = len - sum; i < len; i++) BEAD(i, j) = 1; 33 | } 34 | 35 | // Put sorted values in array using beads 36 | for (int i = 0; i < len; i++) { 37 | int j; 38 | for (j = 0; j < max && BEAD(i, j); j++) { 39 | } 40 | 41 | a[i] = j; 42 | } 43 | delete[] beads; 44 | } 45 | 46 | // driver function to test the algorithm 47 | int main() { 48 | int a[] = {5, 3, 1, 7, 4, 1, 1, 20}; 49 | int len = sizeof(a) / sizeof(a[0]); 50 | 51 | beadSort(a, len); 52 | 53 | for (int i = 0; i < len; i++) printf("%d ", a[i]); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /sorting/bitonic_sort.cpp: -------------------------------------------------------------------------------- 1 | // Source : https://www.geeksforgeeks.org/bitonic-sort/ 2 | 3 | /* C++ Program for Bitonic Sort. Note that this program 4 | works only when size of input is a power of 2. */ 5 | 6 | #include 7 | #include 8 | 9 | /*The parameter dir indicates the sorting direction, ASCENDING 10 | or DESCENDING; if (a[i] > a[j]) agrees with the direction, 11 | then a[i] and a[j] are interchanged.*/ 12 | void compAndSwap(int a[], int i, int j, int dir) { 13 | if (dir == (a[i] > a[j])) 14 | std::swap(a[i], a[j]); 15 | } 16 | 17 | /*It recursively sorts a bitonic sequence in ascending order, 18 | if dir = 1, and in descending order otherwise (means dir=0). 19 | The sequence to be sorted starts at index position low, 20 | the parameter cnt is the number of elements to be sorted.*/ 21 | void bitonicMerge(int a[], int low, int cnt, int dir) { 22 | if (cnt > 1) { 23 | int k = cnt / 2; 24 | for (int i = low; i < low + k; i++) compAndSwap(a, i, i + k, dir); 25 | bitonicMerge(a, low, k, dir); 26 | bitonicMerge(a, low + k, k, dir); 27 | } 28 | } 29 | 30 | /* This function first produces a bitonic sequence by recursively 31 | sorting its two halves in opposite sorting orders, and then 32 | calls bitonicMerge to make them in the same order */ 33 | void bitonicSort(int a[], int low, int cnt, int dir) { 34 | if (cnt > 1) { 35 | int k = cnt / 2; 36 | 37 | // sort in ascending order since dir here is 1 38 | bitonicSort(a, low, k, 1); 39 | 40 | // sort in descending order since dir here is 0 41 | bitonicSort(a, low + k, k, 0); 42 | 43 | // Will merge wole sequence in ascending order 44 | // since dir=1. 45 | bitonicMerge(a, low, cnt, dir); 46 | } 47 | } 48 | 49 | /* Caller of bitonicSort for sorting the entire array of 50 | length N in ASCENDING order */ 51 | void sort(int a[], int N, int up) { bitonicSort(a, 0, N, up); } 52 | 53 | // Driver code 54 | int main() { 55 | int a[] = {3, 7, 4, 8, 6, 2, 1, 5}; 56 | int N = sizeof(a) / sizeof(a[0]); 57 | 58 | int up = 1; // means sort in ascending order 59 | sort(a, N, up); 60 | 61 | std::cout << "Sorted array: \n"; 62 | for (int i = 0; i < N; i++) std::cout << a[i] << " "; 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /sorting/bucket_sort.cpp: -------------------------------------------------------------------------------- 1 | // C++ program to sort an array using bucket sort 2 | #include 3 | #include 4 | #include 5 | 6 | // Function to sort arr[] of size n using bucket sort 7 | void bucketSort(float arr[], int n) { 8 | // 1) Create n empty buckets 9 | std::vector *b = new std::vector[n]; 10 | 11 | // 2) Put array elements in different buckets 12 | for (int i = 0; i < n; i++) { 13 | int bi = n * arr[i]; // Index in bucket 14 | b[bi].push_back(arr[i]); 15 | } 16 | 17 | // 3) Sort individual buckets 18 | for (int i = 0; i < n; i++) std::sort(b[i].begin(), b[i].end()); 19 | 20 | // 4) Concatenate all buckets into arr[] 21 | int index = 0; 22 | for (int i = 0; i < n; i++) 23 | for (int j = 0; j < b[i].size(); j++) arr[index++] = b[i][j]; 24 | delete[] b; 25 | } 26 | 27 | /* Driver program to test above funtion */ 28 | int main() { 29 | float arr[] = {0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434}; 30 | int n = sizeof(arr) / sizeof(arr[0]); 31 | bucketSort(arr, n); 32 | 33 | std::cout << "Sorted array is \n"; 34 | for (int i = 0; i < n; i++) std::cout << arr[i] << " "; 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /sorting/counting_sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int Max(int Arr[], int N) { 5 | int max = Arr[0]; 6 | for (int i = 1; i < N; i++) 7 | if (Arr[i] > max) 8 | max = Arr[i]; 9 | return max; 10 | } 11 | 12 | int Min(int Arr[], int N) { 13 | int min = Arr[0]; 14 | for (int i = 1; i < N; i++) 15 | if (Arr[i] < min) 16 | min = Arr[i]; 17 | return min; 18 | } 19 | 20 | void Print(int Arr[], int N) { 21 | for (int i = 0; i < N; i++) cout << Arr[i] << ", "; 22 | } 23 | 24 | int *Counting_Sort(int Arr[], int N) { 25 | int max = Max(Arr, N); 26 | int min = Min(Arr, N); 27 | int *Sorted_Arr = new int[N]; 28 | 29 | int *Count = new int[max - min + 1]; 30 | for (int i = 0; i < max - min + 1; ++i) { 31 | Count[i] = 0; 32 | } 33 | 34 | for (int i = 0; i < N; i++) Count[Arr[i] - min]++; 35 | 36 | for (int i = 1; i < (max - min + 1); i++) Count[i] += Count[i - 1]; 37 | 38 | for (int i = N - 1; i >= 0; i--) { 39 | Sorted_Arr[Count[Arr[i] - min] - 1] = Arr[i]; 40 | Count[Arr[i] - min]--; 41 | } 42 | 43 | delete[] Count; 44 | return Sorted_Arr; 45 | } 46 | 47 | int main() { 48 | int Arr[] = {47, 65, 20, 66, 25, 53, 64, 69, 72, 22, 49 | 74, 25, 53, 15, 42, 36, 4, 69, 86, 19}, 50 | N = 20; 51 | int *Sorted_Arr; 52 | 53 | cout << "\n\tOrignal Array = "; 54 | Print(Arr, N); 55 | Sorted_Arr = Counting_Sort(Arr, N); 56 | cout << "\n\t Sorted Array = "; 57 | Print(Sorted_Arr, N); 58 | delete[] Sorted_Arr; 59 | cout << endl; 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /sorting/counting_sort_string.cpp: -------------------------------------------------------------------------------- 1 | // C++ Program for counting sort 2 | #include 3 | 4 | using namespace std; 5 | 6 | void countSort(string arr) { 7 | string output; 8 | 9 | int count[256], i; 10 | for (int i = 0; i < 256; i++) count[i] = 0; 11 | 12 | for (i = 0; arr[i]; ++i) ++count[arr[i]]; 13 | 14 | for (i = 1; i < 256; ++i) count[i] += count[i - 1]; 15 | 16 | for (i = 0; arr[i]; ++i) { 17 | output[count[arr[i]] - 1] = arr[i]; 18 | --count[arr[i]]; 19 | } 20 | 21 | for (i = 0; arr[i]; ++i) arr[i] = output[i]; 22 | 23 | cout << "Sorted character array is " << arr; 24 | } 25 | 26 | int main() { 27 | string arr; 28 | cin >> arr; 29 | 30 | countSort(arr); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /sorting/numeric_string_sort.cpp: -------------------------------------------------------------------------------- 1 | // Using general algorithms to sort a collection of strings results in 2 | // alphanumeric sort. If it is a numeric string, it leads to unnatural sorting 3 | 4 | // eg, an array of strings 1,10,100,2,20,200,3,30,300 5 | // would be sorted in that same order by using conventional sorting, 6 | // even though we know the correct sorting order is 1,2,3,10,20,30,100,200,300 7 | 8 | // This Programme uses a comparator to sort the array in Numerical order instead 9 | // of Alphanumeric order 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | bool NumericSort(std::string a, std::string b) { 17 | while (a[0] == '0') { 18 | a.erase(a.begin()); 19 | } 20 | while (b[0] == '0') { 21 | b.erase(b.begin()); 22 | } 23 | int n = a.length(); 24 | int m = b.length(); 25 | if (n == m) 26 | return a < b; 27 | return n < m; 28 | } 29 | 30 | int main() { 31 | int n; 32 | std::cout << "Enter number of elements to be sorted Numerically\n"; 33 | std::cin >> n; 34 | 35 | std::vector v(n); 36 | std::cout << "Enter the string of Numbers\n"; 37 | for (int i = 0; i < n; i++) { 38 | std::cin >> v[i]; 39 | } 40 | 41 | sort(v.begin(), v.end()); 42 | std::cout << "Elements sorted normally \n"; 43 | for (int i = 0; i < n; i++) { 44 | std::cout << v[i] << " "; 45 | } 46 | std::cout << "\n"; 47 | 48 | std::sort(v.begin(), v.end(), NumericSort); 49 | std::cout << "Elements sorted Numerically \n"; 50 | for (int i = 0; i < n; i++) { 51 | std::cout << v[i] << " "; 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /sorting/odd_even_sort.cpp: -------------------------------------------------------------------------------- 1 | /* C++ implementation Odd Even Sort */ 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void oddEven(vector &arr, int size) { 8 | bool sorted = false; 9 | while (!sorted) { 10 | sorted = true; 11 | for (int i = 1; i < size - 1; i += 2) // Odd 12 | { 13 | if (arr[i] > arr[i + 1]) { 14 | swap(arr[i], arr[i + 1]); 15 | sorted = false; 16 | } 17 | } 18 | 19 | for (int i = 0; i < size - 1; i += 2) // Even 20 | { 21 | if (arr[i] > arr[i + 1]) { 22 | swap(arr[i], arr[i + 1]); 23 | sorted = false; 24 | } 25 | } 26 | } 27 | } 28 | 29 | void show(vector A, int size) { 30 | int i; 31 | for (i = 0; i < size; i++) cout << A[i] << "\n"; 32 | } 33 | 34 | int main() { 35 | int size, temp; 36 | cout << "\nEnter the number of elements : "; 37 | cin >> size; 38 | 39 | vector arr; 40 | 41 | cout << "\nEnter the unsorted elements : \n"; 42 | 43 | for (int i = 0; i < size; ++i) { 44 | cin >> temp; 45 | arr.push_back(temp); 46 | } 47 | 48 | oddEven(arr, size); 49 | 50 | cout << "Sorted array\n"; 51 | show(arr, size); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /sorting/radix_sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void radixsort(int a[], int n) { 7 | int count[10]; 8 | int* output = new int[n]; 9 | memset(output, 0, n * sizeof(*output)); 10 | memset(count, 0, sizeof(count)); 11 | int max = 0; 12 | for (int i = 0; i < n; ++i) { 13 | if (a[i] > max) { 14 | max = a[i]; 15 | } 16 | } 17 | int maxdigits = 0; 18 | while (max) { 19 | maxdigits++; 20 | max /= 10; 21 | } 22 | for (int j = 0; j < maxdigits; j++) { 23 | for (int i = 0; i < n; i++) { 24 | int t = std::pow(10, j); 25 | count[(a[i] % (10 * t)) / t]++; 26 | } 27 | int k = 0; 28 | for (int p = 0; p < 10; p++) { 29 | for (int i = 0; i < n; i++) { 30 | int t = std::pow(10, j); 31 | if ((a[i] % (10 * t)) / t == p) { 32 | output[k] = a[i]; 33 | k++; 34 | } 35 | } 36 | } 37 | memset(count, 0, sizeof(count)); 38 | for (int i = 0; i < n; ++i) { 39 | a[i] = output[i]; 40 | } 41 | } 42 | delete[] output; 43 | } 44 | 45 | void print(int a[], int n) { 46 | for (int i = 0; i < n; ++i) { 47 | std::cout << a[i] << " "; 48 | } 49 | std::cout << std::endl; 50 | } 51 | 52 | int main(int argc, char const* argv[]) { 53 | int a[] = {170, 45, 75, 90, 802, 24, 2, 66}; 54 | int n = sizeof(a) / sizeof(a[0]); 55 | radixsort(a, n); 56 | print(a, n); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /sorting/shell_sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int size = 10; 5 | int* array = new int[size]; 6 | // Input 7 | std::cout << "\nHow many numbers do want to enter in unsorted array : "; 8 | std::cin >> size; 9 | std::cout << "\nEnter the numbers for unsorted array : "; 10 | for (int i = 0; i < size; i++) { 11 | std::cin >> array[i]; 12 | } 13 | 14 | // Sorting 15 | for (int i = size / 2; i > 0; i = i / 2) { 16 | for (int j = i; j < size; j++) { 17 | for (int k = j - i; k >= 0; k = k - i) { 18 | if (array[k] < array[k + i]) { 19 | break; 20 | } else { 21 | int temp = array[k + i]; 22 | array[k + i] = array[k]; 23 | array[k] = temp; 24 | } 25 | } 26 | } 27 | } 28 | 29 | // Output 30 | std::cout << "\nSorted array : "; 31 | for (int i = 0; i < size; ++i) { 32 | std::cout << array[i] << "\t"; 33 | } 34 | 35 | delete[] array; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /sorting/slow_sort.cpp: -------------------------------------------------------------------------------- 1 | // Returns the sorted vector after performing SlowSort 2 | // It is a sorting algorithm that is of humorous nature and not useful. 3 | // It's based on the principle of multiply and surrender, a tongue-in-cheek joke 4 | // of divide and conquer. It was published in 1986 by Andrei Broder and Jorge 5 | // Stolfi in their paper Pessimal Algorithms and Simplexity Analysis. This 6 | // algorithm multiplies a single problem into multiple subproblems It is 7 | // interesting because it is provably the least efficient sorting algorithm that 8 | // can be built asymptotically, and with the restriction that such an algorithm, 9 | // while being slow, must still all the time be working towards a result. 10 | 11 | #include 12 | 13 | void SlowSort(int a[], int i, int j) { 14 | if (i >= j) 15 | return; 16 | int m = i + (j - i) / 2; // midpoint, implemented this way to avoid 17 | // overflow 18 | int temp; 19 | SlowSort(a, i, m); 20 | SlowSort(a, m + 1, j); 21 | if (a[j] < a[m]) { 22 | temp = a[j]; // swapping a[j] & a[m] 23 | a[j] = a[m]; 24 | a[m] = temp; 25 | } 26 | SlowSort(a, i, j - 1); 27 | } 28 | 29 | // Sample Main function 30 | 31 | int main() { 32 | int size; 33 | std::cout << "\nEnter the number of elements : "; 34 | 35 | std::cin >> size; 36 | 37 | int *arr = new int[size]; 38 | 39 | std::cout << "\nEnter the unsorted elements : "; 40 | 41 | for (int i = 0; i < size; ++i) { 42 | std::cout << "\n"; 43 | std::cin >> arr[i]; 44 | } 45 | 46 | SlowSort(arr, 0, size); 47 | 48 | std::cout << "Sorted array\n"; 49 | 50 | for (int i = 0; i < size; ++i) { 51 | std::cout << arr[i] << " "; 52 | } 53 | 54 | delete[] arr; 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /sorting/stooge_sort.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief [Stooge sort implementation](https://en.wikipedia.org/wiki/Stooge_sort) 4 | * in C++ 5 | * @details 6 | * Stooge sort is a recursive sorting algorithm. 7 | * It divides the array into 3 parts and proceeds to: 8 | * - sort first two thirds of the array 9 | * - sort last two thirds of the array 10 | * - sort first two thirds of the array 11 | * It's time complexity is O(n^(log3/log1.5)), which is about O(n^2.7), 12 | * which makes it to be not the most efficient sorting algorithm 13 | * on the street on average. Space complexity is O(1). 14 | */ 15 | 16 | #include /// for vector 17 | #include /// for assert 18 | #include /// for std::is_sorted 19 | #include /// for IO operations 20 | 21 | /** 22 | * @brief The stoogeSort() function is used for sorting the array. 23 | * @param L - vector of values (int) to be sorted in in place (ascending order) 24 | * @param i - the first index of the array (0) 25 | * @param j - the last index of the array (L.size() - 1) 26 | * @returns void 27 | */ 28 | void stoogeSort(std::vector* L, size_t i, size_t j) { 29 | if (i >= j) { 30 | return; 31 | } 32 | if ((*L)[i] > (*L)[j]) { 33 | std::swap((*L)[i], (*L)[j]); 34 | } 35 | if (j - i > 1) { 36 | size_t third = (j - i + 1) / 3; 37 | stoogeSort(L, i, j - third); 38 | stoogeSort(L, i + third, j); 39 | stoogeSort(L, i, j - third); 40 | } 41 | } 42 | 43 | /** 44 | * @brief Function to test sorting algorithm 45 | * @returns void 46 | */ 47 | void test1() { 48 | std::vector L = { 8, 9, 10, 4, 3, 5, 1 }; 49 | stoogeSort(&L, 0, L.size() - 1); 50 | assert(std::is_sorted(std::begin(L), std::end(L))); 51 | } 52 | 53 | /** 54 | * @brief Function to test sorting algorithm, one element 55 | * @returns void 56 | */ 57 | void test2() { 58 | std::vector L = { -1 }; 59 | stoogeSort(&L, 0, L.size() - 1); 60 | assert(std::is_sorted(std::begin(L), std::end(L))); 61 | } 62 | 63 | /** 64 | * @brief Function to test sorting algorithm, repeating elements 65 | * @returns void 66 | */ 67 | void test3() { 68 | std::vector L = { 1, 2, 5, 4, 1, 5 }; 69 | stoogeSort(&L, 0, L.size() - 1); 70 | assert(std::is_sorted(std::begin(L), std::end(L))); 71 | } 72 | 73 | /** 74 | * @brief Main function 75 | * @param argc commandline argument count (ignored) 76 | * @param argv commandline array of arguments (ignored) 77 | * @returns 0 on exit 78 | */ 79 | int main() { 80 | test1(); 81 | test2(); 82 | test3(); 83 | 84 | std::cout << "All tests have successfully passed!\n"; 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /sorting/swap_sort.cpp: -------------------------------------------------------------------------------- 1 | // C++ program to find minimum number of swaps required to sort an array 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Function returns the minimum number of swaps 8 | // required to sort the array 9 | int minSwaps(int arr[], int n) { 10 | // Create an array of pairs where first 11 | // element is array element and second element 12 | // is position of first element 13 | std::pair *arrPos = new std::pair[n]; 14 | for (int i = 0; i < n; i++) { 15 | arrPos[i].first = arr[i]; 16 | arrPos[i].second = i; 17 | } 18 | 19 | // Sort the array by array element values to 20 | // get right position of every element as second 21 | // element of pair. 22 | std::sort(arrPos, arrPos + n); 23 | 24 | // To keep track of visited elements. Initialize 25 | // all elements as not visited or false. 26 | std::vector vis(n, false); 27 | 28 | // Initialize result 29 | int ans = 0; 30 | 31 | // Traverse array elements 32 | for (int i = 0; i < n; i++) { 33 | // already swapped and corrected or 34 | // already present at correct pos 35 | if (vis[i] || arrPos[i].second == i) 36 | continue; 37 | 38 | // find out the number of node in 39 | // this cycle and add in ans 40 | int cycle_size = 0; 41 | int j = i; 42 | while (!vis[j]) { 43 | vis[j] = 1; 44 | 45 | // move to next node 46 | j = arrPos[j].second; 47 | cycle_size++; 48 | } 49 | 50 | // Update answer by adding current cycle. 51 | if (cycle_size > 0) { 52 | ans += (cycle_size - 1); 53 | } 54 | } 55 | 56 | delete[] arrPos; 57 | 58 | // Return result 59 | return ans; 60 | } 61 | 62 | // program to test 63 | int main() { 64 | int arr[] = {6, 7, 8, 1, 2, 3, 9, 12}; 65 | int n = (sizeof(arr) / sizeof(int)); 66 | std::cout << minSwaps(arr, n); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /strings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # If necessary, use the RELATIVE flag, otherwise each source file may be listed 2 | # with full pathname. RELATIVE may makes it easier to extract an executable name 3 | # automatically. 4 | file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 5 | # file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) 6 | # AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) 7 | foreach( testsourcefile ${APP_SOURCES} ) 8 | # I used a simple string replace, to cut off .cpp. 9 | string( REPLACE ".cpp" "" testname ${testsourcefile} ) 10 | add_executable( ${testname} ${testsourcefile} ) 11 | 12 | set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) 13 | if(OpenMP_CXX_FOUND) 14 | target_link_libraries(${testname} OpenMP::OpenMP_CXX) 15 | endif() 16 | install(TARGETS ${testname} DESTINATION "bin/strings") 17 | 18 | endforeach( testsourcefile ${APP_SOURCES} ) 19 | -------------------------------------------------------------------------------- /strings/brute_force_string_searching.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief String pattern search - brute force 4 | */ 5 | #include 6 | #ifdef _MSC_VER 7 | #include // use this for MS Visual C++ 8 | #else 9 | #include 10 | #endif 11 | #include 12 | 13 | namespace string_search { 14 | /** 15 | * Find a pattern in a string by comparing the pattern to every substring. 16 | * @param text Any string that might contain the pattern. 17 | * @param pattern String that we are searching for. 18 | * @return Index where the pattern starts in the text 19 | * @return -1 if the pattern was not found. 20 | */ 21 | int brute_force(const std::string &text, const std::string &pattern) { 22 | size_t pat_l = pattern.length(); 23 | size_t txt_l = text.length(); 24 | int index = -1; 25 | if (pat_l <= txt_l) { 26 | for (size_t i = 0; i < txt_l - pat_l + 1; i++) { 27 | std::string s = text.substr(i, pat_l); 28 | if (s == pattern) { 29 | index = i; 30 | break; 31 | } 32 | } 33 | } 34 | return index; 35 | } 36 | } // namespace string_search 37 | 38 | using string_search::brute_force; 39 | 40 | /** set of test cases */ 41 | const std::vector> test_set = { 42 | // {text, pattern, expected output} 43 | {"a", "aa", "-1"}, {"a", "a", "0"}, {"ba", "b", "0"}, 44 | {"bba", "bb", "0"}, {"bbca", "c", "2"}, {"ab", "b", "1"}}; 45 | 46 | /** Main function */ 47 | int main() { 48 | for (const auto &i : test_set) { 49 | int output = brute_force(i[0], i[1]); 50 | 51 | if (std::to_string(output) == i[2]) { 52 | std::cout << "success\n"; 53 | } else { 54 | std::cout << "failure\n"; 55 | } 56 | } 57 | return 0; 58 | } 59 | --------------------------------------------------------------------------------