├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── new_implementation.yml │ └── other.yml ├── PULL_REQUEST_TEMPLATE │ └── pull_request.md ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── citk.yml │ ├── godocmd.yml │ ├── stale.yml │ └── upload_coverage_report.yml ├── .gitignore ├── .gitpod.dockerfile ├── .gitpod.yml ├── .golangci.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── STYLE.md ├── cache ├── lfu.go ├── lfu_test.go ├── lru.go └── lru_test.go ├── checksum ├── crc8.go ├── crc8_test.go ├── luhn.go └── luhn_test.go ├── cipher ├── caesar │ ├── caesar.go │ └── caesar_test.go ├── cipher_test.go ├── diffiehellman │ ├── diffiehellmankeyexchange.go │ └── diffiehellmankeyexchange_test.go ├── doc.go ├── dsa │ ├── dsa.go │ └── dsa_test.go ├── polybius │ ├── polybius.go │ └── polybius_test.go ├── railfence │ ├── railfence.go │ └── railfence_test.go ├── rot13 │ ├── rot13.go │ └── rot13_test.go ├── rsa │ ├── rsa.go │ ├── rsa2.go │ ├── rsa2_test.go │ └── rsa_test.go ├── transposition │ ├── transposition.go │ └── transposition_test.go └── xor │ ├── xor.go │ └── xor_test.go ├── compression ├── huffmancoding.go ├── huffmancoding_test.go ├── rlecoding.go └── rlecoding_test.go ├── constraints └── constraints.go ├── conversion ├── base64.go ├── base64_test.go ├── binarytodecimal.go ├── binarytodecimal_test.go ├── conversion_test.go ├── decimaltobinary.go ├── decimaltobinary_test.go ├── doc.go ├── hexadecimaltobinary.go ├── hexadecimaltobinary_test.go ├── hexadecimaltodecimal.go ├── hexadecimaltodecimal_test.go ├── inttoroman.go ├── inttoroman_test.go ├── rgbhex.go ├── rgbhex_test.go ├── romantoint.go └── romantoint_test.go ├── dynamic ├── abbreviation.go ├── abbreviation_test.go ├── binomialcoefficient.go ├── binomialcoefficient_test.go ├── burstballoons.go ├── burstballoons_test.go ├── catalan.go ├── catalan_test.go ├── coinchange.go ├── coinchange_test.go ├── dicethrow.go ├── dicethrow_test.go ├── doc.go ├── dynamic_test.go ├── editdistance.go ├── editdistance_test.go ├── eggdropping.go ├── eggdropping_test.go ├── fibonacci.go ├── fibonacci_test.go ├── interleavingstrings.go ├── interleavingstrings_test.go ├── knapsack.go ├── knapsack_test.go ├── longestarithmeticsubsequence.go ├── longestarithmeticsubsequence_test.go ├── longestcommonsubsequence.go ├── longestcommonsubsequence_test.go ├── longestincreasingsubsequence.go ├── longestincreasingsubsequence_test.go ├── longestincreasingsubsequencegreedy.go ├── longestpalindromicsubsequence.go ├── longestpalindromicsubsequence_test.go ├── longestpalindromicsubstring.go ├── longestpalindromicsubstring_test.go ├── matrixmultiplication.go ├── maxsubarraysum.go ├── maxsubarraysum_test.go ├── optimalbst.go ├── optimalbst_test.go ├── partitionproblem.go ├── partitionproblem_test.go ├── rodcutting.go ├── rodcutting_test.go ├── subsetsum.go ├── subsetsum_test.go ├── tilingproblem.go ├── tilingproblem_test.go ├── traprainwater.go ├── traprainwater_test.go ├── uniquepaths.go ├── uniquepaths_test.go ├── wildcardmatching.go ├── wildcardmatching_test.go ├── wordbreak.go └── wordbreak_test.go ├── go.mod ├── go.sum ├── graph ├── articulationpoints.go ├── articulationpoints_test.go ├── bellmanford.go ├── bellmanford_test.go ├── breadthfirstsearch.go ├── breadthfirstsearch_test.go ├── coloring │ ├── backtracking.go │ ├── backtracking_test.go │ ├── bfs.go │ ├── bfs_test.go │ ├── bipartite.go │ ├── bipartite_test.go │ ├── doc.go │ ├── graph.go │ ├── graph_test.go │ ├── greedy.go │ └── greedy_test.go ├── cycle.go ├── cycle_test.go ├── depthfirstsearch.go ├── depthfirstsearch_test.go ├── dijkstra.go ├── dijkstra_test.go ├── doc.go ├── edmondkarp.go ├── edmondkarp_test.go ├── floydwarshall.go ├── floydwarshall_test.go ├── graph.go ├── graph_test.go ├── kahn.go ├── kahn_test.go ├── kosaraju.go ├── kosaraju_test.go ├── kruskal.go ├── kruskal_test.go ├── lowestcommonancestor.go ├── lowestcommonancestor_test.go ├── prim.go ├── prim_test.go ├── topological.go ├── topological_test.go ├── unionfind.go └── unionfind_test.go ├── hashing ├── doc.go ├── hashing_test.go ├── md5 │ ├── md5.go │ └── md5_test.go ├── sha1 │ ├── sha1.go │ └── sha1_test.go └── sha256 │ ├── sha256.go │ └── sha256_test.go ├── math ├── abs.go ├── abs_test.go ├── aliquot_test.go ├── aliquotsum.go ├── armstrong │ ├── isarmstrong.go │ └── isarmstrong_test.go ├── binary │ ├── abs.go │ ├── abs_test.go │ ├── arithmeticmean.go │ ├── arithmeticmean_test.go │ ├── bitcounter.go │ ├── bitcounter_test.go │ ├── checkisnumberpoweroftwo.go │ ├── checkisnumberpoweroftwo_test.go │ ├── fast_inverse_sqrt.go │ ├── logarithm.go │ ├── logarithm_test.go │ ├── rbc.go │ ├── rbc_test.go │ ├── reversebits.go │ ├── reversebits_test.go │ ├── sqrt.go │ ├── sqrt_test.go │ ├── xorsearch.go │ └── xorsearch_test.go ├── binomialcoefficient.go ├── binomialcoefficient_test.go ├── catalan │ ├── catalannumber.go │ └── catalannumber_test.go ├── checkisnumberpoweroftwo.go ├── checkisnumberpoweroftwo_test.go ├── cos.go ├── cos_test.go ├── doc.go ├── eulertotient.go ├── eulertotient_test.go ├── factorial │ ├── factorial.go │ └── factorial_test.go ├── fibonacci │ ├── fibonacci.go │ └── fibonacci_test.go ├── gcd │ ├── extended.go │ ├── extended_test.go │ ├── extendedgcd.go │ ├── extendedgcd_test.go │ ├── extendedgcditerative.go │ ├── gcd.go │ ├── gcd_test.go │ └── gcditerative.go ├── geometry │ ├── distance.go │ ├── distance_test.go │ ├── straightlines.go │ └── straightlines_test.go ├── isautomorphic.go ├── isautomorphic_test.go ├── krishnamurthy.go ├── krishnamurthy_test.go ├── kthnumber.go ├── kthnumber_test.go ├── lcm │ ├── lcm.go │ └── lcm_test.go ├── lerp.go ├── lerp_test.go ├── liouville.go ├── liouville_test.go ├── math_test.go ├── matrix │ ├── add.go │ ├── add_test.go │ ├── checkequal.go │ ├── checkequal_test.go │ ├── copy.go │ ├── copy_test.go │ ├── determinant.go │ ├── determinant_test.go │ ├── isvalid.go │ ├── isvalid_test.go │ ├── matchdimensions.go │ ├── matchdimensions_test.go │ ├── matrix.go │ ├── matrix_test.go │ ├── multiply.go │ ├── multiply_test.go │ ├── strassenmatrixmultiply.go │ ├── strassenmatrixmultiply_test.go │ ├── string.go │ ├── string_test.go │ ├── submatrix.go │ ├── submatrix_test.go │ ├── subtract.go │ └── subtract_test.go ├── max │ ├── bitwisemax.go │ ├── bitwisemax_test.go │ ├── max.go │ └── max_test.go ├── mean.go ├── mean_test.go ├── median.go ├── median_test.go ├── min │ ├── bitwisemin.go │ ├── min.go │ └── min_test.go ├── mobius.go ├── mobius_test.go ├── mode.go ├── mode_test.go ├── modular │ ├── exponentiation.go │ ├── exponentiation_test.go │ ├── inverse.go │ └── inverse_test.go ├── moserdebruijnsequence │ ├── sequence.go │ └── sequence_test.go ├── pascal │ ├── pascaltriangle.go │ └── pascaltriangle_test.go ├── perfectnumber.go ├── perfectnumber_test.go ├── permutation │ ├── heaps.go │ ├── heaps_test.go │ ├── next_permutation.go │ └── next_permutation_test.go ├── pi │ ├── montecarlopi.go │ ├── montecarlopi_test.go │ ├── spigotpi.go │ └── spigotpi_test.go ├── pollard.go ├── pollard_test.go ├── power │ ├── fastexponent.go │ ├── fastexponent_test.go │ ├── powvialogarithm.go │ └── powvialogarithm_test.go ├── prime │ ├── millerrabintest.go │ ├── prime_test.go │ ├── primecheck.go │ ├── primefactorization.go │ ├── primefactorization_test.go │ ├── sieve.go │ ├── sieve2.go │ ├── sieve2_test.go │ ├── sieve_test.go │ ├── twin.go │ └── twin_test.go ├── pronicnumber.go ├── pronicnumber_test.go ├── pythagoras │ ├── pythagoras.go │ └── pythagoras_test.go ├── sin.go └── sin_test.go ├── other ├── doc.go ├── maxsubarraysum │ ├── maxsubarraysum.go │ └── maxsubarraysum_test.go ├── nested │ ├── nestedbrackets.go │ └── nestedbrackets_test.go ├── other_test.go └── password │ └── generator.go ├── project_euler ├── problem_1 │ ├── problem1.go │ └── problem1_test.go ├── problem_10 │ ├── problem10.go │ └── problem10_test.go ├── problem_11 │ ├── problem11.go │ └── problem11_test.go ├── problem_12 │ ├── problem12.go │ └── problem12_test.go ├── problem_13 │ ├── problem13.go │ └── problem13_test.go ├── problem_14 │ ├── problem14.go │ └── problem14_test.go ├── problem_15 │ ├── problem15.go │ └── problem15_test.go ├── problem_16 │ ├── problem16.go │ └── problem16_test.go ├── problem_17 │ ├── input.go │ ├── problem17.go │ └── problem17_test.go ├── problem_18 │ ├── edge.go │ ├── input.go │ ├── leaf.go │ ├── problem18.go │ ├── problem18_test.go │ ├── root.go │ └── tree.go ├── problem_19 │ ├── problem19.go │ └── problem19_test.go ├── problem_2 │ ├── problem2.go │ └── problem2_test.go ├── problem_20 │ ├── problem20.go │ └── problem20_test.go ├── problem_3 │ ├── problem3.go │ └── problem3_test.go ├── problem_4 │ ├── problem4.go │ └── problem4_test.go ├── problem_5 │ ├── problem5.go │ └── problem5_test.go ├── problem_6 │ ├── problem6.go │ └── problem6_test.go ├── problem_7 │ ├── problem7.go │ └── problem7_test.go ├── problem_8 │ ├── problem8.go │ └── problem8_test.go └── problem_9 │ ├── problem9.go │ └── problem9_test.go ├── search ├── binary.go ├── binary_test.go ├── doc.go ├── errors.go ├── interpolation.go ├── interpolation_test.go ├── jump.go ├── jump2.go ├── jump2_test.go ├── jump_test.go ├── linear.go ├── linear_test.go ├── selectk.go ├── selectk_test.go ├── ternary.go ├── ternary_test.go └── testcases.go ├── sort ├── binaryinsertionsort.go ├── bogosort.go ├── bubblesort.go ├── bucketsort.go ├── circlesort.go ├── cocktailsort.go ├── combSort.go ├── countingsort.go ├── cyclesort.go ├── doc.go ├── exchangesort.go ├── heapsort.go ├── insertionsort.go ├── mergesort.go ├── oddevensort.go ├── pancakesort.go ├── patiencesort.go ├── pigeonholesort.go ├── quicksort.go ├── radixsort.go ├── selectionsort.go ├── shellsort.go ├── simplesort.go ├── sorts_test.go ├── stooge_sort.go └── timsort.go ├── sqrt ├── sqrtdecomposition.go └── sqrtdecomposition_test.go ├── strings ├── ahocorasick │ ├── advancedahocorasick.go │ ├── advancedahocorasick_test.go │ ├── ahocorasick.go │ ├── ahocorasick_test.go │ ├── patterns.txt │ ├── shared.go │ └── text.txt ├── bom │ └── bom.go ├── charoccurrence.go ├── charoccurrence_test.go ├── combination │ └── combination.go ├── doc.go ├── generateparentheses │ ├── generateparentheses.go │ └── generateparentheses_test.go ├── genetic │ ├── genetic.go │ └── geneticalgorithm_test.go ├── guid │ ├── guid.go │ └── guid_test.go ├── hamming │ ├── hammingdistance.go │ └── hammingdistance_test.go ├── horspool │ ├── horspool.go │ └── horspool_test.go ├── isisogram.go ├── isisogram_test.go ├── issubsequence.go ├── issubsequence_test.go ├── kmp │ ├── kmp.go │ └── kmp_test.go ├── levenshtein │ ├── levenshteindistance.go │ └── levenshteindistance_test.go ├── manacher │ ├── longestpalindrome.go │ └── longestpalindrome_test.go ├── palindrome │ ├── ispalindrome.go │ └── ispalindrome_test.go ├── pangram │ ├── ispangram.go │ └── ispangram_test.go ├── parenthesis │ ├── parenthesis.go │ └── parenthesis_test.go ├── search │ ├── boyermoore.go │ ├── naive.go │ └── patternsearch_test.go └── strings_test.go └── structure ├── circularqueue ├── circularqueue_test.go └── circularqueuearray.go ├── deque ├── deque.go └── deque_test.go ├── doc.go ├── dynamicarray ├── dynamicarray.go └── dynamicarray_test.go ├── fenwicktree ├── fenwicktree.go └── fenwicktree_test.go ├── hashmap ├── hashmap.go └── hashmap_test.go ├── heap ├── heap.go └── heap_test.go ├── linkedlist ├── Linked_Cyclic_List.jpg ├── Readme.md ├── cyclic.go ├── cyclic_test.go ├── doc.go ├── doubly.go ├── doubly_test.go ├── shared.go ├── singlylinkedlist.go └── singlylinkedlist_test.go ├── queue ├── queue_test.go ├── queuearray.go ├── queuelinkedlist.go └── queuelinklistwithlist.go ├── segmenttree ├── segmenttree.go └── segmenttree_test.go ├── set ├── set.go ├── set_test.go └── setexample_test.go ├── stack ├── stack_test.go ├── stackarray.go ├── stacklinkedlist.go └── stacklinkedlistwithlist.go ├── structure_test.go ├── tree ├── avl.go ├── avl_test.go ├── bstree.go ├── bstree_test.go ├── btree.go ├── btree_test.go ├── example_test.go ├── rbtree.go ├── rbtree_test.go ├── tree.go └── tree_test.go └── trie ├── trie.go ├── trie_bench_test.go ├── trie_test.go └── trieexample_test.go /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This is a comment. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # More details are here: https://help.github.com/articles/about-codeowners/ 5 | 6 | # The '*' pattern is global owners. 7 | 8 | # Order is important. The last matching pattern has the most precedence. 9 | 10 | * @raklaptudirm @yanglbme 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/other.yml: -------------------------------------------------------------------------------- 1 | name: Other 2 | description: Use this for any other issues. Do NOT create blank issues 3 | title: "[OTHER]" 4 | labels: ["awaiting triage"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: "# Other issue" 9 | - type: textarea 10 | id: issuedescription 11 | attributes: 12 | label: What would you like to share? 13 | description: Provide a clear and concise explanation of your issue. 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: extrainfo 18 | attributes: 19 | label: Additional information 20 | description: Is there anything else we should know about this issue? 21 | validations: 22 | required: false 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/pull_request.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/Go/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 - [GoDoc guidelines](https://blog.golang.org/godoc) 16 | - [ ] Relevant documentation/comments is changed or added 17 | - [ ] PR title follows semantic [commit guidelines](https://github.com/TheAlgorithms/Go/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: -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Keep GitHub Actions up to date with GitHub's Dependabot... 2 | # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot 3 | # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem 4 | version: 2 5 | updates: 6 | - package-ecosystem: github-actions 7 | directory: / 8 | groups: 9 | github-actions: 10 | patterns: 11 | - "*" # Group all Actions updates into a single larger pull request 12 | schedule: 13 | interval: weekly 14 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/golangci/golangci-lint 2 | name: Continuous Integration 3 | on: 4 | push: 5 | # prevent duplication of tests with 6 | # `pull_request` event 7 | branches: 8 | - master 9 | pull_request: 10 | 11 | jobs: 12 | golang_lint_and_test: 13 | name: Code style and tests 14 | runs-on: ubuntu-latest 15 | strategy: 16 | fail-fast: false 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Setup Go 20 | uses: actions/setup-go@v5 21 | with: 22 | go-version: '^1.18' 23 | - name: Run Golang CI Lint 24 | uses: golangci/golangci-lint-action@v6 25 | with: 26 | version: latest 27 | args: -E gofmt 28 | - name: Run tests 29 | run: go test ./... 30 | codespell: 31 | name: Check for spelling errors 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/checkout@v4 35 | - uses: codespell-project/actions-codespell@master 36 | with: 37 | ignore_words_list: "actualy,nwe" 38 | skip: "go.mod,go.sum" 39 | -------------------------------------------------------------------------------- /.github/workflows/citk.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/golangci/golangci-lint 2 | name: CI tool kit 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | CITK: 8 | name: Code style and tests 9 | runs-on: ubuntu-latest 10 | strategy: 11 | fail-fast: false 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | - name: Setup Go 17 | uses: actions/setup-go@v5 18 | with: 19 | go-version: "^1.18" 20 | - name: Checkout branch 21 | run: | 22 | git fetch origin master:master 23 | - name: Install citk tool 24 | run: | 25 | go install github.com/tjgurwara99/citk@latest 26 | - name: Run citk tool 27 | run: | 28 | citk check -l go -b master 29 | -------------------------------------------------------------------------------- /.github/workflows/godocmd.yml: -------------------------------------------------------------------------------- 1 | name: Generate Documentation 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | generate_readme: 9 | name: Markdown Generation 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | fetch-depth: 0 15 | - uses: actions/setup-go@v5 16 | with: 17 | go-version: '^1.18' 18 | - name: Install GoDocMD 19 | run: | 20 | go install github.com/tjgurwara99/godocmd@v0.1.3 21 | - name: Configure Github Action 22 | run: | 23 | git config --global user.name "$GITHUB_ACTOR" 24 | git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" 25 | - name: Update README.md file 26 | run: | 27 | godocmd -r -module ./ -w 28 | - name: Commit changes if README.md is different 29 | run: | 30 | if [[ `git status --porcelain` ]]; then 31 | git commit -am "Updated Documentation in README.md" 32 | git push 33 | else 34 | echo "NO CHANGES DETECTED" 35 | fi 36 | -------------------------------------------------------------------------------- /.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@v9 10 | with: 11 | stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' 12 | close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' 13 | stale-pr-message: 'This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' 14 | close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' 15 | exempt-issue-labels: 'dont-close' 16 | exempt-pr-labels: 'dont-close' 17 | days-before-stale: 30 18 | days-before-close: 7 19 | -------------------------------------------------------------------------------- /.github/workflows/upload_coverage_report.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: upload_coverage_report 3 | 4 | on: 5 | workflow_dispatch: 6 | push: 7 | branches: 8 | - master 9 | pull_request: 10 | 11 | env: 12 | REPORT_NAME: "coverage.out" 13 | 14 | jobs: 15 | upload_coverage_report: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Setup Go 20 | uses: actions/setup-go@v5 21 | with: 22 | go-version: '^1.18' 23 | - name: Generate code coverage 24 | run: | 25 | go test -coverprofile="${{ env.REPORT_NAME }}" ./... 26 | - name: Upload coverage to codecov (tokenless) 27 | if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository 28 | uses: codecov/codecov-action@v5 29 | with: 30 | files: "${{ env.REPORT_NAME }}" 31 | fail_ci_if_error: true 32 | - name: Upload coverage to codecov (with token) 33 | if: "! github.event.pull_request.head.repo.fork " 34 | uses: codecov/codecov-action@v5 35 | with: 36 | token: ${{ secrets.CODECOV_TOKEN }} 37 | files: "${{ env.REPORT_NAME }}" 38 | fail_ci_if_error: true 39 | ... 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | coverage.out 4 | -------------------------------------------------------------------------------- /.gitpod.dockerfile: -------------------------------------------------------------------------------- 1 | FROM gitpod/workspace-go 2 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | --- 2 | image: 3 | file: .gitpod.dockerfile 4 | 5 | tasks: 6 | - init: | 7 | echo "Welcome to TheAlgorithms/Go" 8 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | go: 1.19 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 The Algorithms and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /checksum/luhn.go: -------------------------------------------------------------------------------- 1 | // lunh.go 2 | // description: Luhn algorithm 3 | // details: is a simple checksum formula used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers, etc [Lunh](https://en.wikipedia.org/wiki/Luhn_algorithm) 4 | // time complexity: O(n) 5 | // space complexity: O(1) 6 | // author(s) [red_byte](https://github.com/i-redbyte) 7 | // see lunh_test.go 8 | 9 | // Package checksum describes algorithms for finding various checksums 10 | package checksum 11 | 12 | // Luhn validates the provided data using the Luhn algorithm. 13 | func Luhn(s []byte) bool { 14 | n := len(s) 15 | number := 0 16 | result := 0 17 | for i := 0; i < n; i++ { 18 | number = int(s[i]) - '0' 19 | if i%2 != 0 { 20 | result += number 21 | continue 22 | } 23 | number *= 2 24 | if number > 9 { 25 | number -= 9 26 | } 27 | result += number 28 | } 29 | return result%10 == 0 30 | } 31 | -------------------------------------------------------------------------------- /checksum/luhn_test.go: -------------------------------------------------------------------------------- 1 | // luhn_test.go 2 | // description: Test for Luhn algorithm 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see luhn.go 5 | 6 | package checksum_test 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/TheAlgorithms/Go/checksum" 12 | ) 13 | 14 | func TestLuhn(t *testing.T) { 15 | tests := []struct { 16 | name string 17 | s []byte 18 | want bool 19 | }{ 20 | {"check 4242424242424242", []byte("4242424242424242"), true}, 21 | {"check 6200000000000005", []byte("6200000000000005"), true}, 22 | {"check 5534200028533164", []byte("5534200028533164"), true}, 23 | {"check 36227206271667", []byte("36227206271667"), true}, 24 | {"check 471629309440", []byte("471629309440"), false}, 25 | {"check 1111", []byte("1111"), false}, 26 | {"check 12345674", []byte("12345674"), true}, 27 | } 28 | for _, test := range tests { 29 | t.Run(test.name, func(t *testing.T) { 30 | if got := checksum.Luhn(test.s); got != test.want { 31 | t.Errorf("LuhnAlgorithm() = %v, want %v", got, test.want) 32 | } 33 | }) 34 | } 35 | } 36 | 37 | func BenchmarkBruteForceFactorial(b *testing.B) { 38 | for i := 0; i < b.N; i++ { 39 | checksum.Luhn([]byte("4242424242424242")) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /cipher/cipher_test.go: -------------------------------------------------------------------------------- 1 | // Empty test file to keep track of all the tests for the algorithms. 2 | 3 | package cipher 4 | -------------------------------------------------------------------------------- /cipher/doc.go: -------------------------------------------------------------------------------- 1 | // Package cipher is a package containing different implementations of certain ciphers 2 | package cipher 3 | -------------------------------------------------------------------------------- /cipher/rot13/rot13.go: -------------------------------------------------------------------------------- 1 | // Package rot13 is a simple letter substitution cipher that replaces a letter with the 13th letter after it in the alphabet. 2 | // description: ROT13 3 | // details: ROT13 is a simple letter substitution cipher that replaces a letter with the 13th letter after it in the alphabet. it is a special case of the Caesar cipher 4 | // time complexity: O(n) 5 | // space complexity: O(n) 6 | // ref: https://en.wikipedia.org/wiki/ROT13 7 | package rot13 8 | 9 | import ( 10 | "github.com/TheAlgorithms/Go/cipher/caesar" 11 | ) 12 | 13 | // rot13 is a special case, which is fixed the shift of 13, of the Caesar cipher 14 | func rot13(input string) string { 15 | return caesar.Encrypt(input, 13) 16 | } 17 | -------------------------------------------------------------------------------- /cipher/rsa/rsa2_test.go: -------------------------------------------------------------------------------- 1 | package rsa_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TheAlgorithms/Go/cipher/rsa" 7 | ) 8 | 9 | func TestRSA(t *testing.T) { 10 | tests := []struct { 11 | name string 12 | message string 13 | }{ 14 | { 15 | name: "Encrypt letter 'a' and decrypt it back", 16 | message: "a", 17 | }, 18 | { 19 | name: "Encrypt 'Hello, World!' and decrypt it back", 20 | message: "Hello, World!", 21 | }, 22 | } 23 | 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | rsa := rsa.New() 27 | encrypted := rsa.EncryptString(tt.message) 28 | decrypted := rsa.DecryptString(encrypted) 29 | if decrypted != tt.message { 30 | t.Errorf("expected %s, got %s", tt.message, decrypted) 31 | } 32 | }) 33 | } 34 | } 35 | 36 | func BenchmarkRSAEncryption(b *testing.B) { 37 | rsa := rsa.New() 38 | for i := 0; i < b.N; i++ { 39 | rsa.EncryptString("Hello, World!") 40 | } 41 | } 42 | 43 | func BenchmarkRSADecryption(b *testing.B) { 44 | rsa := rsa.New() 45 | encrypted := rsa.EncryptString("Hello, World!") 46 | for i := 0; i < b.N; i++ { 47 | rsa.DecryptString(encrypted) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /cipher/xor/xor.go: -------------------------------------------------------------------------------- 1 | // Package xor is an encryption algorithm that operates the exclusive disjunction(XOR) 2 | // description: XOR encryption 3 | // details: The XOR encryption is an algorithm that operates the exclusive disjunction(XOR) on each character of the plaintext with a given key 4 | // time complexity: O(n) 5 | // space complexity: O(n) 6 | // ref: https://en.wikipedia.org/wiki/XOR_cipher 7 | package xor 8 | 9 | // Encrypt encrypts with Xor encryption after converting each character to byte 10 | // The returned value might not be readable because there is no guarantee 11 | // which is within the ASCII range 12 | // If using other type such as string, []int, or some other types, 13 | // add the statements for converting the type to []byte. 14 | func Encrypt(key byte, plaintext []byte) []byte { 15 | cipherText := []byte{} 16 | for _, ch := range plaintext { 17 | cipherText = append(cipherText, key^ch) 18 | } 19 | return cipherText 20 | } 21 | 22 | // Decrypt decrypts with Xor encryption 23 | func Decrypt(key byte, cipherText []byte) []byte { 24 | plainText := []byte{} 25 | for _, ch := range cipherText { 26 | plainText = append(plainText, key^ch) 27 | } 28 | return plainText 29 | } 30 | -------------------------------------------------------------------------------- /conversion/binarytodecimal.go: -------------------------------------------------------------------------------- 1 | /* 2 | Author: Motasim 3 | GitHub: https://github.com/motasimmakki 4 | Date: 19-Oct-2021 5 | */ 6 | 7 | // This algorithm will convert any Binary number(0 or 1) to Decimal number(+ve number). 8 | // https://en.wikipedia.org/wiki/Binary_number 9 | // https://en.wikipedia.org/wiki/Decimal 10 | // Function receives a Binary Number as string and returns the Decimal number as integer. 11 | // Supported Binary number range is 0 to 2^(31-1). 12 | // time complexity: O(n) 13 | // space complexity: O(1) 14 | 15 | package conversion 16 | 17 | // Importing necessary package. 18 | import ( 19 | "errors" 20 | "regexp" 21 | ) 22 | 23 | var isValid = regexp.MustCompile("^[0-1]{1,}$").MatchString 24 | 25 | // BinaryToDecimal() function that will take Binary number as string, 26 | // and return its Decimal equivalent as an integer. 27 | func BinaryToDecimal(binary string) (int, error) { 28 | if !isValid(binary) { 29 | return -1, errors.New("not a valid binary string") 30 | } 31 | if len(binary) > 32 { 32 | return -1, errors.New("binary number must be in range 0 to 2^(31-1)") 33 | } 34 | var result, base int = 0, 1 35 | for i := len(binary) - 1; i >= 0; i-- { 36 | if binary[i] == '1' { 37 | result += base 38 | } 39 | base *= 2 40 | } 41 | return result, nil 42 | } 43 | -------------------------------------------------------------------------------- /conversion/conversion_test.go: -------------------------------------------------------------------------------- 1 | // Empty test file to keep track of all the tests for the algorithms. 2 | 3 | package conversion 4 | -------------------------------------------------------------------------------- /conversion/doc.go: -------------------------------------------------------------------------------- 1 | // Package conversion is a package of implementations which converts one data structure to another. 2 | package conversion 3 | -------------------------------------------------------------------------------- /conversion/hexadecimaltobinary_test.go: -------------------------------------------------------------------------------- 1 | package conversion 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestHexToBinary(t *testing.T) { 8 | tests := []struct { 9 | hex string 10 | want string 11 | wantErr bool 12 | }{ 13 | {"", "", true}, 14 | {"G123", "", true}, 15 | {"12XZ", "", true}, 16 | {"1", "1", false}, 17 | {"A", "1010", false}, 18 | {"10", "10000", false}, 19 | {"1A", "11010", false}, 20 | {"aB", "10101011", false}, 21 | {"0Ff", "11111111", false}, 22 | {" 1A ", "11010", false}, 23 | {"0001A", "11010", false}, 24 | {"7FFFFFFFFFFFFFFF", "111111111111111111111111111111111111111111111111111111111111111", false}, 25 | } 26 | 27 | for _, tt := range tests { 28 | t.Run(tt.hex, func(t *testing.T) { 29 | got, err := hexToBinary(tt.hex) 30 | if (err != nil) != tt.wantErr { 31 | t.Errorf("hexToBinary(%q) error = %v, wantErr %v", tt.hex, err, tt.wantErr) 32 | return 33 | } 34 | if got != tt.want { 35 | t.Errorf("hexToBinary(%q) = %v, want %v", tt.hex, got, tt.want) 36 | } 37 | }) 38 | } 39 | } 40 | 41 | func BenchmarkHexToBinary(b *testing.B) { 42 | b.ReportAllocs() 43 | for i := 0; i < b.N; i++ { 44 | _, _ = hexToBinary("7FFFFFFFFFFFFFFF") 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /conversion/inttoroman_test.go: -------------------------------------------------------------------------------- 1 | package conversion 2 | 3 | import "testing" 4 | 5 | func TestIntToRoman(t *testing.T) { 6 | for expected, input := range romanTestCases { 7 | out, err := IntToRoman(input) 8 | if err != nil { 9 | t.Errorf("IntToRoman(%d) returned an error %s", input, err.Error()) 10 | } 11 | if out != expected { 12 | t.Errorf("IntToRoman(%d) = %s; want %s", input, out, expected) 13 | } 14 | } 15 | _, err := IntToRoman(100000) 16 | if err == nil { 17 | t.Errorf("IntToRoman(%d) expected an error", 100000) 18 | } 19 | _, err = IntToRoman(0) 20 | if err == nil { 21 | t.Errorf("IntToRoman(%d) expected an error", 0) 22 | } 23 | } 24 | 25 | func BenchmarkIntToRoman(b *testing.B) { 26 | b.ReportAllocs() 27 | for i := 0; i < b.N; i++ { 28 | _, _ = IntToRoman(3999) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /conversion/rgbhex_test.go: -------------------------------------------------------------------------------- 1 | package conversion 2 | 3 | import "testing" 4 | 5 | var HEX = []uint{ 6 | 0x1abc9c, 7 | 0x3498db, 8 | 0x9b59b6, 9 | } 10 | 11 | var RGB = [][]byte{ 12 | {26, 188, 156}, 13 | {52, 152, 219}, 14 | {155, 89, 182}, 15 | } 16 | 17 | func TestHEXToRGB(t *testing.T) { 18 | for i := 0; i < len(HEX); i++ { 19 | hex := HEX[i] 20 | expected := RGB[i] 21 | resultR, resultG, resultB := HEXToRGB(hex) 22 | if resultR != expected[0] || resultG != expected[1] || resultB != expected[2] { 23 | t.Errorf("HEXToRGB(%d) = %d,%d,%d; want %d,%d,%d", 24 | hex, resultR, resultG, resultB, expected[0], expected[1], expected[2]) 25 | } 26 | } 27 | } 28 | 29 | func BenchmarkHEXToRGB(b *testing.B) { 30 | for i := 0; i < b.N; i++ { 31 | _, _, _ = HEXToRGB(0xdeadbe) 32 | } 33 | } 34 | 35 | func TestRGBToHEX(t *testing.T) { 36 | for i := 0; i < len(RGB); i++ { 37 | args := RGB[i] 38 | expected := HEX[i] 39 | result := RGBToHEX(args[0], args[1], args[2]) 40 | if result != expected { 41 | t.Errorf("RGBToHEX(%d,%d,%d) = %d; want %d", 42 | args[0], args[1], args[2], result, expected) 43 | } 44 | } 45 | } 46 | 47 | func BenchmarkRGBToHEX(b *testing.B) { 48 | for i := 0; i < b.N; i++ { 49 | _ = RGBToHEX(222, 173, 190) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /dynamic/abbreviation_test.go: -------------------------------------------------------------------------------- 1 | package dynamic 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestAbbreviation(t *testing.T) { 9 | tests := []struct { 10 | a string 11 | b string 12 | expected bool 13 | }{ 14 | {"uOHlGMdUBc", "uOalGMdUBCasdcavsdf", false}, 15 | {"kotgDIUagj", "DIU", true}, 16 | {"WPTffVkSNl", "WPTVSN", true}, 17 | {"CoJsPURrVX", "CPUVX", false}, 18 | {"xasreDHndqvCnFfX", "DHndqvCnFX", false}, 19 | {"XFEaWCxpeepGjOnCCsFh", "XFEAWCPEPGOCCSF", true}, 20 | {"", "", true}, 21 | {"a", "", true}, 22 | {"a", "b", false}, 23 | {"a", "a", false}, 24 | {"A", "A", true}, 25 | } 26 | count := len(tests) 27 | for i := 0; i < count; i++ { 28 | name := fmt.Sprintf( 29 | "Test case #%d: string a = \"%s\", string b = \"%s\"", 30 | i+1, 31 | tests[i].a, 32 | tests[i].b, 33 | ) 34 | t.Run(name, func(t *testing.T) { 35 | result := Abbreviation(tests[i].a, tests[i].b) 36 | if result != tests[i].expected { 37 | t.Errorf("Expected the %t, got %t", tests[i].expected, result) 38 | } 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dynamic/binomialcoefficient_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/TheAlgorithms/Go/dynamic" 8 | ) 9 | 10 | func TestBin2(t *testing.T) { 11 | td := []struct { 12 | n, k, expected int 13 | }{ 14 | {0, 0, 1}, 15 | {1, 1, 1}, 16 | {2, 0, 1}, {2, 1, 2}, {2, 2, 1}, 17 | {3, 0, 1}, {3, 1, 3}, {3, 2, 3}, {3, 3, 1}, 18 | {4, 0, 1}, {4, 1, 4}, {4, 2, 6}, {4, 3, 4}, {4, 4, 1}, 19 | {5, 0, 1}, {5, 1, 5}, {5, 2, 10}, {5, 3, 10}, {5, 4, 5}, {5, 5, 1}, 20 | {10, 2, 45}, 21 | {15, 10, 3003}, 22 | } 23 | for _, tc := range td { 24 | name := fmt.Sprintf("binomial coefficient of (%d, %d)", tc.n, tc.k) 25 | t.Run(name, func(t *testing.T) { 26 | actual := dynamic.Bin2(tc.n, tc.k) 27 | if actual != tc.expected { 28 | t.Errorf("expecting binomial coefficient of (%d, %d) to be %d but got %d", tc.n, tc.k, tc.expected, actual) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dynamic/burstballoons.go: -------------------------------------------------------------------------------- 1 | package dynamic 2 | 3 | import "github.com/TheAlgorithms/Go/math/max" 4 | 5 | // MaxCoins returns the maximum coins we can collect by bursting the balloons 6 | func MaxCoins(nums []int) int { 7 | n := len(nums) 8 | if n == 0 { 9 | return 0 10 | } 11 | 12 | nums = append([]int{1}, nums...) 13 | nums = append(nums, 1) 14 | 15 | dp := make([][]int, n+2) 16 | for i := range dp { 17 | dp[i] = make([]int, n+2) 18 | } 19 | 20 | for length := 1; length <= n; length++ { 21 | for left := 1; left+length-1 <= n; left++ { 22 | right := left + length - 1 23 | for k := left; k <= right; k++ { 24 | coins := nums[left-1] * nums[k] * nums[right+1] 25 | dp[left][right] = max.Int(dp[left][right], dp[left][k-1]+dp[k+1][right]+coins) 26 | } 27 | } 28 | } 29 | 30 | return dp[1][n] 31 | } 32 | -------------------------------------------------------------------------------- /dynamic/burstballoons_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TheAlgorithms/Go/dynamic" 7 | ) 8 | 9 | type testCaseBurstBalloons struct { 10 | nums []int 11 | expected int 12 | } 13 | 14 | func getBurstBalloonsTestCases() []testCaseBurstBalloons { 15 | return []testCaseBurstBalloons{ 16 | {[]int{3, 1, 5, 8}, 167}, // Maximum coins from [3,1,5,8] 17 | {[]int{1, 5}, 10}, // Maximum coins from [1,5] 18 | {[]int{1}, 1}, // Single balloon 19 | {[]int{}, 0}, // No balloons 20 | } 21 | 22 | } 23 | 24 | func TestMaxCoins(t *testing.T) { 25 | t.Run("Burst Balloons test cases", func(t *testing.T) { 26 | for _, tc := range getBurstBalloonsTestCases() { 27 | actual := dynamic.MaxCoins(tc.nums) 28 | if actual != tc.expected { 29 | t.Errorf("MaxCoins(%v) = %d; expected %d", tc.nums, actual, tc.expected) 30 | } 31 | } 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /dynamic/catalan.go: -------------------------------------------------------------------------------- 1 | //The Catalan numbers are a sequence of positive integers that appear in many counting 2 | // problems in combinatorics. 3 | // time complexity: O(n²) 4 | // space complexity: O(n) 5 | //reference: https://brilliant.org/wiki/catalan-numbers/ 6 | 7 | package dynamic 8 | 9 | import "fmt" 10 | 11 | var errCatalan = fmt.Errorf("can't have a negative n-th catalan number") 12 | 13 | // NthCatalan returns the n-th Catalan Number 14 | // Complexity: O(n²) 15 | func NthCatalanNumber(n int) (int64, error) { 16 | if n < 0 { 17 | //doesn't accept negative number 18 | return 0, errCatalan 19 | } 20 | 21 | var catalanNumberList []int64 22 | catalanNumberList = append(catalanNumberList, 1) //first value is 1 23 | 24 | for i := 1; i <= n; i++ { 25 | catalanNumberList = append(catalanNumberList, 0) //append 0 and calculate 26 | 27 | for j := 0; j < i; j++ { 28 | catalanNumberList[i] += catalanNumberList[j] * catalanNumberList[i-j-1] 29 | } 30 | } 31 | 32 | return catalanNumberList[n], nil 33 | } 34 | -------------------------------------------------------------------------------- /dynamic/coinchange.go: -------------------------------------------------------------------------------- 1 | // coinchange.go 2 | // description: Implementation of the coin change problem using dynamic programming 3 | // details: The coin change problem is a problem that asks for the number of ways to make change for a given amount of money using a given set of coins. The problem can be solved using dynamic programming. 4 | // time complexity: O(n*m) where n is the number of coins and m is the amount of money 5 | // space complexity: O(m) where m is the amount of money 6 | 7 | package dynamic 8 | 9 | // CoinChange finds the number of possible combinations of coins 10 | // of different values which can get to the target amount. 11 | func CoinChange(coins []int32, amount int32) int32 { 12 | combination := make([]int32, amount) 13 | combination[0] = 1 14 | 15 | for _, c := range coins { 16 | for i := c; i < amount; i++ { 17 | 18 | combination[i] += combination[i-c] 19 | } 20 | } 21 | 22 | return combination[amount-1] 23 | } 24 | -------------------------------------------------------------------------------- /dynamic/coinchange_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/TheAlgorithms/Go/dynamic" 6 | "testing" 7 | ) 8 | 9 | func TestCoinChange(t *testing.T) { 10 | coinCombination := []int32{1, 2, 5, 10} 11 | targets := []struct { 12 | target int32 13 | expected int32 14 | }{ 15 | {4, 2}, 16 | {5, 3}, 17 | {10, 8}, 18 | {15, 19}, 19 | {20, 34}, 20 | } 21 | 22 | for _, v := range targets { 23 | t.Run(fmt.Sprintf("target: %d ", v.target), func(t *testing.T) { 24 | result := dynamic.CoinChange(coinCombination, v.target) 25 | if result != v.expected { 26 | t.Errorf("target: %d Expected %d, got %d", v.target, v.expected, result) 27 | } 28 | }) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /dynamic/dicethrow.go: -------------------------------------------------------------------------------- 1 | // dicethrow.go 2 | // description: Solves the Dice Throw Problem using dynamic programming 3 | // reference: https://www.geeksforgeeks.org/dice-throw-problem/ 4 | // time complexity: O(m * n) 5 | // space complexity: O(m * n) 6 | 7 | package dynamic 8 | 9 | // DiceThrow returns the number of ways to get sum `sum` using `m` dice with `n` faces 10 | func DiceThrow(m, n, sum int) int { 11 | dp := make([][]int, m+1) 12 | for i := range dp { 13 | dp[i] = make([]int, sum+1) 14 | } 15 | 16 | for i := 1; i <= n; i++ { 17 | if i <= sum { 18 | dp[1][i] = 1 19 | } 20 | } 21 | 22 | for i := 2; i <= m; i++ { 23 | for j := 1; j <= sum; j++ { 24 | for k := 1; k <= n; k++ { 25 | if j-k >= 0 { 26 | dp[i][j] += dp[i-1][j-k] 27 | } 28 | } 29 | } 30 | } 31 | 32 | return dp[m][sum] 33 | } 34 | -------------------------------------------------------------------------------- /dynamic/doc.go: -------------------------------------------------------------------------------- 1 | // Package dynamic is a package of certain implementations of dynamically run algorithms. 2 | package dynamic 3 | -------------------------------------------------------------------------------- /dynamic/dynamic_test.go: -------------------------------------------------------------------------------- 1 | // Empty test file to keep track of all the tests for the algorithms. 2 | 3 | package dynamic 4 | -------------------------------------------------------------------------------- /dynamic/editdistance_test.go: -------------------------------------------------------------------------------- 1 | package dynamic 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func Test_EditDistance(t *testing.T) { 9 | 10 | var testCases = []struct { 11 | first string 12 | second string 13 | expected int 14 | }{ 15 | {"", "", 0}, 16 | {"horse", "ros", 3}, 17 | {"intention", "execution", 5}, 18 | {"abcdxabcde", "abcdeabcdx", 2}, 19 | {"sunday", "saturday", 3}, 20 | {"food", "money", 4}, 21 | {"voldemort", "dumbledore", 7}, 22 | } 23 | 24 | for i := range testCases { 25 | 26 | t.Run(fmt.Sprintf("Word 1: %s, Word 2: %s", testCases[i].first, testCases[i].second), func(t *testing.T) { 27 | 28 | computed := EditDistanceDP(testCases[i].first, testCases[i].second) 29 | 30 | if computed != testCases[i].expected { 31 | t.Errorf("Word 1: %s, Word 2: %s, Expected: %d, Computed: %d", testCases[i].first, testCases[i].second, testCases[i].expected, computed) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dynamic/eggdropping_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TheAlgorithms/Go/dynamic" 7 | ) 8 | 9 | type testCaseEggDropping struct { 10 | eggs int 11 | floors int 12 | expected int 13 | } 14 | 15 | func getEggDroppingTestCases() []testCaseEggDropping { 16 | return []testCaseEggDropping{ 17 | {1, 10, 10}, // One egg, need to test all floors 18 | {2, 10, 4}, // Two eggs and ten floors 19 | {3, 14, 4}, // Three eggs and fourteen floors 20 | {2, 36, 8}, // Two eggs and thirty-six floors 21 | {2, 0, 0}, // Two eggs, zero floors 22 | } 23 | 24 | } 25 | 26 | func TestEggDropping(t *testing.T) { 27 | t.Run("Egg Dropping test cases", func(t *testing.T) { 28 | for _, tc := range getEggDroppingTestCases() { 29 | actual := dynamic.EggDropping(tc.eggs, tc.floors) 30 | if actual != tc.expected { 31 | t.Errorf("EggDropping(%d, %d) = %d; expected %d", tc.eggs, tc.floors, actual, tc.expected) 32 | } 33 | } 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /dynamic/fibonacci.go: -------------------------------------------------------------------------------- 1 | // fibonacci.go 2 | // description: Implementation of the Fibonacci sequence using dynamic programming 3 | // time complexity: O(n) 4 | // space complexity: O(1) 5 | package dynamic 6 | 7 | // https://www.geeksforgeeks.org/program-for-nth-fibonacci-number/ 8 | 9 | // NthFibonacci returns the nth Fibonacci Number 10 | func NthFibonacci(n uint) uint { 11 | if n == 0 { 12 | return 0 13 | } 14 | 15 | // n1 and n2 are the (i-1)th and ith Fibonacci numbers, respectively 16 | var n1, n2 uint = 0, 1 17 | 18 | for i := uint(1); i < n; i++ { 19 | n3 := n1 + n2 20 | n1 = n2 21 | n2 = n3 22 | } 23 | 24 | return n2 25 | } 26 | -------------------------------------------------------------------------------- /dynamic/fibonacci_test.go: -------------------------------------------------------------------------------- 1 | package dynamic 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func Test_NthFibonacci(t *testing.T) { 9 | // source: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html 10 | var fibonacciNumbers = []struct { 11 | nth uint 12 | fibonacci uint 13 | }{ 14 | {0, 0}, 15 | {1, 1}, 16 | {2, 1}, 17 | {3, 2}, 18 | {4, 3}, 19 | {5, 5}, 20 | {6, 8}, 21 | {7, 13}, 22 | {8, 21}, 23 | {9, 34}, 24 | {10, 55}, 25 | {20, 6765}, 26 | {30, 832040}, 27 | {40, 102334155}, 28 | {50, 12586269025}, 29 | {60, 1548008755920}, 30 | {70, 190392490709135}, 31 | {80, 23416728348467685}, 32 | {90, 2880067194370816120}, 33 | } 34 | for i := range fibonacciNumbers { 35 | t.Run(fmt.Sprintf("the %dth Fibonacci number", fibonacciNumbers[i].nth), func(t *testing.T) { 36 | result := NthFibonacci(fibonacciNumbers[i].nth) 37 | if result != fibonacciNumbers[i].fibonacci { 38 | t.Errorf("Expected the %dth Fibonacci number to be %d, got %d", fibonacciNumbers[i].nth, fibonacciNumbers[i].fibonacci, result) 39 | } 40 | }) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dynamic/interleavingstrings.go: -------------------------------------------------------------------------------- 1 | // interleavingstrings.go 2 | // description: Solves the Interleaving Strings problem using dynamic programming 3 | // reference: https://en.wikipedia.org/wiki/Interleaving_strings 4 | // time complexity: O(m*n) 5 | // space complexity: O(m*n) 6 | 7 | package dynamic 8 | 9 | // IsInterleave checks if string `s1` and `s2` can be interleaved to form string `s3` 10 | func IsInterleave(s1, s2, s3 string) bool { 11 | if len(s1)+len(s2) != len(s3) { 12 | return false 13 | } 14 | 15 | dp := make([][]bool, len(s1)+1) 16 | for i := range dp { 17 | dp[i] = make([]bool, len(s2)+1) 18 | } 19 | 20 | dp[0][0] = true 21 | for i := 1; i <= len(s1); i++ { 22 | dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1] 23 | } 24 | 25 | for j := 1; j <= len(s2); j++ { 26 | dp[0][j] = dp[0][j-1] && s2[j-1] == s3[j-1] 27 | } 28 | 29 | for i := 1; i <= len(s1); i++ { 30 | for j := 1; j <= len(s2); j++ { 31 | dp[i][j] = (dp[i-1][j] && s1[i-1] == s3[i+j-1]) || (dp[i][j-1] && s2[j-1] == s3[i+j-1]) 32 | } 33 | } 34 | 35 | return dp[len(s1)][len(s2)] 36 | } 37 | -------------------------------------------------------------------------------- /dynamic/knapsack.go: -------------------------------------------------------------------------------- 1 | package dynamic 2 | 3 | // Knapsack Problem 4 | // https://www.geeksforgeeks.org/0-1-knapsack-problem-dp-10/ 5 | // https://en.wikipedia.org/wiki/Knapsack_problem 6 | // time complexity: O(n*maxWeight) 7 | // space complexity: O(n*maxWeight) 8 | 9 | import ( 10 | "math" 11 | ) 12 | 13 | // Max function - possible duplicate 14 | func Max(a, b int) int { 15 | return int(math.Max(float64(a), float64(b))) 16 | } 17 | 18 | // Knapsack solves knapsack problem 19 | // return maxProfit 20 | func Knapsack(maxWeight int, weights, values []int) int { 21 | n := len(weights) 22 | m := maxWeight 23 | // create dp data structure 24 | dp := make([][]int, n+1) 25 | for i := range dp { 26 | dp[i] = make([]int, m+1) 27 | } 28 | for i := 0; i < len(weights); i++ { 29 | for j := 0; j <= maxWeight; j++ { 30 | if weights[i] > j { 31 | dp[i+1][j] = dp[i][j] 32 | } else { 33 | dp[i+1][j] = Max(dp[i][j-weights[i]]+values[i], dp[i][j]) 34 | } 35 | } 36 | } 37 | return dp[n][m] 38 | } 39 | 40 | /* 41 | func main() { 42 | maxWeight := 50 43 | values := []int{ 44 | 60, 100, 120, 45 | } 46 | weights := []int{ 47 | 10, 20, 30, 48 | } 49 | maxProfit := Knapsack(maxWeight, weights, values) 50 | fmt.Println(maxProfit) 51 | } 52 | */ 53 | -------------------------------------------------------------------------------- /dynamic/longestarithmeticsubsequence.go: -------------------------------------------------------------------------------- 1 | // longestarithmeticsubsequence.go 2 | // description: Implementation of the Longest Arithmetic Subsequence problem 3 | // reference: https://en.wikipedia.org/wiki/Longest_arithmetic_progression 4 | // time complexity: O(n^2) 5 | // space complexity: O(n^2) 6 | 7 | package dynamic 8 | 9 | // LongestArithmeticSubsequence returns the length of the longest arithmetic subsequence 10 | func LongestArithmeticSubsequence(nums []int) int { 11 | n := len(nums) 12 | if n <= 1 { 13 | return n 14 | } 15 | 16 | dp := make([]map[int]int, n) 17 | for i := range dp { 18 | dp[i] = make(map[int]int) 19 | } 20 | 21 | maxLength := 1 22 | 23 | for i := 1; i < n; i++ { 24 | for j := 0; j < i; j++ { 25 | diff := nums[i] - nums[j] 26 | dp[i][diff] = dp[j][diff] + 1 27 | if dp[i][diff]+1 > maxLength { 28 | maxLength = dp[i][diff] + 1 29 | } 30 | } 31 | } 32 | 33 | return maxLength 34 | } 35 | -------------------------------------------------------------------------------- /dynamic/longestcommonsubsequence.go: -------------------------------------------------------------------------------- 1 | // LONGEST COMMON SUBSEQUENCE 2 | // DP - 4 3 | // https://www.geeksforgeeks.org/longest-common-subsequence-dp-4/ 4 | // https://leetcode.com/problems/longest-common-subsequence/ 5 | // time complexity: O(m*n) where m and n are lengths of the strings 6 | // space complexity: O(m*n) where m and n are lengths of the strings 7 | 8 | package dynamic 9 | 10 | func strToRuneSlice(s string) (r []rune, size int) { 11 | r = []rune(s) 12 | return r, len(r) 13 | } 14 | 15 | // LongestCommonSubsequence function 16 | func LongestCommonSubsequence(a string, b string) int { 17 | aRunes, aLen := strToRuneSlice(a) 18 | bRunes, bLen := strToRuneSlice(b) 19 | 20 | // here we are making a 2d slice of size (aLen+1)*(bLen+1) 21 | lcs := make([][]int, aLen+1) 22 | for i := 0; i <= aLen; i++ { 23 | lcs[i] = make([]int, bLen+1) 24 | } 25 | 26 | // block that implements LCS 27 | for i := 0; i <= aLen; i++ { 28 | for j := 0; j <= bLen; j++ { 29 | if i == 0 || j == 0 { 30 | lcs[i][j] = 0 31 | } else if aRunes[i-1] == bRunes[j-1] { 32 | lcs[i][j] = lcs[i-1][j-1] + 1 33 | } else { 34 | lcs[i][j] = Max(lcs[i-1][j], lcs[i][j-1]) 35 | } 36 | } 37 | } 38 | // returning the length of longest common subsequence 39 | return lcs[aLen][bLen] 40 | } 41 | -------------------------------------------------------------------------------- /dynamic/longestincreasingsubsequence.go: -------------------------------------------------------------------------------- 1 | // longestincreasingsubsequence.go 2 | // description: Implementation of the Longest Increasing Subsequence using dynamic programming 3 | // reference: https://en.wikipedia.org/wiki/Longest_increasing_subsequence 4 | // time complexity: O(n^2) 5 | // space complexity: O(n) 6 | 7 | package dynamic 8 | 9 | import ( 10 | "github.com/TheAlgorithms/Go/math/max" 11 | ) 12 | 13 | // LongestIncreasingSubsequence returns the longest increasing subsequence 14 | // where all elements of the subsequence are sorted in increasing order 15 | func LongestIncreasingSubsequence(elements []int) int { 16 | n := len(elements) 17 | lis := make([]int, n) 18 | for i := range lis { 19 | lis[i] = 1 20 | } 21 | for i := range lis { 22 | for j := 0; j < i; j++ { 23 | if elements[i] > elements[j] && lis[i] < lis[j]+1 { 24 | lis[i] = lis[j] + 1 25 | } 26 | } 27 | } 28 | res := 0 29 | for _, value := range lis { 30 | res = max.Int(res, value) 31 | } 32 | return res 33 | } 34 | -------------------------------------------------------------------------------- /dynamic/longestincreasingsubsequence_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/TheAlgorithms/Go/dynamic" 8 | ) 9 | 10 | func longestIncreasingSubsequenceTest(t *testing.T, algorithm func(nums []int) int) { 11 | td := []struct { 12 | elements []int 13 | expectedLen int 14 | }{ 15 | {[]int{1, 2, 3, 4, 5, 10}, 6}, 16 | {[]int{1, 7, 3, 4, 5}, 4}, // 1,3,4,5 17 | {[]int{1, 3, 5}, 3}, 18 | {[]int{7, 1, 6}, 2}, 19 | {[]int{4, 1, 6, 2}, 2}, 20 | {[]int{11, 9, 6}, 1}, 21 | } 22 | for _, tc := range td { 23 | t.Run(fmt.Sprint("test with", tc.elements), func(t *testing.T) { 24 | actualLen := algorithm(tc.elements) 25 | if tc.expectedLen != actualLen { 26 | t.Fatalf("expecting a sequence of len %d to be found but the actual len was %d; input: %v", tc.expectedLen, actualLen, tc.elements) 27 | } 28 | }) 29 | } 30 | } 31 | 32 | func TestLongestIncreasingSubsequence(t *testing.T) { 33 | longestIncreasingSubsequenceTest(t, dynamic.LongestIncreasingSubsequence) 34 | } 35 | 36 | func TestLongestIncreasingSubsequenceGreedy(t *testing.T) { 37 | longestIncreasingSubsequenceTest(t, dynamic.LongestIncreasingSubsequenceGreedy) 38 | } 39 | -------------------------------------------------------------------------------- /dynamic/longestpalindromicsubsequence.go: -------------------------------------------------------------------------------- 1 | // longest palindromic subsequence 2 | // time complexity: O(n^2) 3 | // space complexity: O(n^2) 4 | // http://www.geeksforgeeks.org/dynamic-programming-set-12-longest-palindromic-subsequence/ 5 | 6 | package dynamic 7 | 8 | func lpsRec(word string, i, j int) int { 9 | if i == j { 10 | return 1 11 | } 12 | if i > j { 13 | return 0 14 | } 15 | if word[i] == word[j] { 16 | return 2 + lpsRec(word, i+1, j-1) 17 | } 18 | return Max(lpsRec(word, i, j-1), lpsRec(word, i+1, j)) 19 | } 20 | 21 | // LpsRec function 22 | func LpsRec(word string) int { 23 | return lpsRec(word, 0, len(word)-1) 24 | } 25 | 26 | // LpsDp function 27 | func LpsDp(word string) int { 28 | N := len(word) 29 | dp := make([][]int, N) 30 | 31 | for i := 0; i < N; i++ { 32 | dp[i] = make([]int, N) 33 | dp[i][i] = 1 34 | } 35 | 36 | for l := 2; l <= N; l++ { 37 | // for length l 38 | for i := 0; i < N-l+1; i++ { 39 | j := i + l - 1 40 | if word[i] == word[j] { 41 | if l == 2 { 42 | dp[i][j] = 2 43 | } else { 44 | dp[i][j] = 2 + dp[i+1][j-1] 45 | } 46 | } else { 47 | dp[i][j] = Max(dp[i+1][j], dp[i][j-1]) 48 | } 49 | } 50 | } 51 | 52 | return dp[0][N-1] 53 | } 54 | -------------------------------------------------------------------------------- /dynamic/longestpalindromicsubsequence_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/TheAlgorithms/Go/dynamic" 8 | ) 9 | 10 | func lpsTestTemplate(t *testing.T, algorithm func(input string) int) { 11 | testCases := []struct { 12 | input string 13 | expected int 14 | }{ 15 | {"BBABCBCAB", 7}, 16 | {"BBBAB", 4}, 17 | {"ABBD", 2}, 18 | {"GEEKSFORGEEKS", 5}, 19 | {"abcdefgh", 1}, 20 | {"bbbab", 4}, 21 | {"cbbd", 2}, 22 | {"racexyzcxar", 7}, 23 | } 24 | for _, tc := range testCases { 25 | t.Run(fmt.Sprint("test with ", tc.input), func(t *testing.T) { 26 | result := algorithm(tc.input) 27 | if tc.expected != result { 28 | t.Fatalf("expected %d, got %d", tc.expected, result) 29 | } 30 | }) 31 | } 32 | } 33 | 34 | func TestLpsRec(t *testing.T) { 35 | lpsTestTemplate(t, dynamic.LpsRec) 36 | } 37 | 38 | func TestLpsDp(t *testing.T) { 39 | lpsTestTemplate(t, dynamic.LpsDp) 40 | } 41 | -------------------------------------------------------------------------------- /dynamic/longestpalindromicsubstring.go: -------------------------------------------------------------------------------- 1 | // longestpalindromicsubstring.go 2 | // description: Implementation of finding the longest palindromic substring 3 | // reference: https://en.wikipedia.org/wiki/Longest_palindromic_substring 4 | // time complexity: O(n^2) 5 | // space complexity: O(n^2) 6 | 7 | package dynamic 8 | 9 | // LongestPalindromicSubstring returns the longest palindromic substring in the input string 10 | func LongestPalindromicSubstring(s string) string { 11 | n := len(s) 12 | if n == 0 { 13 | return "" 14 | } 15 | 16 | dp := make([][]bool, n) 17 | for i := range dp { 18 | dp[i] = make([]bool, n) 19 | } 20 | 21 | start := 0 22 | maxLength := 1 23 | for i := 0; i < n; i++ { 24 | dp[i][i] = true 25 | } 26 | 27 | for length := 2; length <= n; length++ { 28 | for i := 0; i < n-length+1; i++ { 29 | j := i + length - 1 30 | if length == 2 { 31 | dp[i][j] = (s[i] == s[j]) 32 | } else { 33 | dp[i][j] = (s[i] == s[j]) && dp[i+1][j-1] 34 | } 35 | 36 | if dp[i][j] && length > maxLength { 37 | maxLength = length 38 | start = i 39 | } 40 | } 41 | } 42 | return s[start : start+maxLength] 43 | } 44 | -------------------------------------------------------------------------------- /dynamic/maxsubarraysum.go: -------------------------------------------------------------------------------- 1 | // maxsubarraysum.go 2 | // description: Implementation of Kadane's algorithm for Maximum Subarray Sum 3 | // reference: https://en.wikipedia.org/wiki/Maximum_subarray_problem 4 | // time complexity: O(n) 5 | // space complexity: O(1) 6 | 7 | package dynamic 8 | 9 | import "github.com/TheAlgorithms/Go/math/max" 10 | 11 | // MaxSubArraySum returns the sum of the maximum subarray in the input array 12 | func MaxSubArraySum(nums []int) int { 13 | maxSum := nums[0] 14 | currentSum := nums[0] 15 | 16 | for i := 1; i < len(nums); i++ { 17 | currentSum = max.Int(nums[i], currentSum+nums[i]) 18 | maxSum = max.Int(maxSum, currentSum) 19 | } 20 | 21 | return maxSum 22 | } 23 | -------------------------------------------------------------------------------- /dynamic/optimalbst_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TheAlgorithms/Go/dynamic" 7 | ) 8 | 9 | type testCaseOptimalBST struct { 10 | keys []int 11 | freq []int 12 | n int 13 | expected int 14 | } 15 | 16 | func getOptimalBSTTestCases() []testCaseOptimalBST { 17 | return []testCaseOptimalBST{ 18 | {[]int{10, 12, 20}, []int{34, 8, 50}, 3, 142}, // Example with 3 keys 19 | {[]int{10, 20, 30, 40, 50}, []int{10, 20, 30, 40, 50}, 5, 300}, // Example with 5 keys 20 | {[]int{10}, []int{100}, 1, 100}, // Single key case 21 | } 22 | } 23 | 24 | func TestOptimalBST(t *testing.T) { 25 | t.Run("Optimal Binary Search Tree test cases", func(t *testing.T) { 26 | for _, tc := range getOptimalBSTTestCases() { 27 | t.Run("testing optimal BST", func(t *testing.T) { 28 | actual := dynamic.OptimalBST(tc.keys, tc.freq, tc.n) 29 | if actual != tc.expected { 30 | t.Errorf("OptimalBST(%v, %v, %d) = %d; expected %d", tc.keys, tc.freq, tc.n, actual, tc.expected) 31 | } 32 | }) 33 | } 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /dynamic/partitionproblem.go: -------------------------------------------------------------------------------- 1 | // partitionproblem.go 2 | // description: Solves the Partition Problem using dynamic programming 3 | // reference: https://en.wikipedia.org/wiki/Partition_problem 4 | // time complexity: O(n*sum) 5 | // space complexity: O(n*sum) 6 | 7 | package dynamic 8 | 9 | // PartitionProblem checks whether the given set can be partitioned into two subsets 10 | // such that the sum of the elements in both subsets is the same. 11 | func PartitionProblem(nums []int) bool { 12 | sum := 0 13 | for _, num := range nums { 14 | sum += num 15 | } 16 | if sum%2 != 0 { 17 | return false 18 | } 19 | 20 | target := sum / 2 21 | dp := make([]bool, target+1) 22 | dp[0] = true 23 | 24 | for _, num := range nums { 25 | for i := target; i >= num; i-- { 26 | dp[i] = dp[i] || dp[i-num] 27 | } 28 | } 29 | return dp[target] 30 | } 31 | -------------------------------------------------------------------------------- /dynamic/rodcutting_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TheAlgorithms/Go/dynamic" 7 | ) 8 | 9 | type rodCuttingTestCase struct { 10 | price []int 11 | length int 12 | expected int 13 | } 14 | 15 | func getRodCuttingTestCases() []rodCuttingTestCase { 16 | return []rodCuttingTestCase{ 17 | {[]int{0, 1, 5, 8, 9}, 4, 10}, 18 | {[]int{0, 2, 5, 7, 8, 0}, 5, 12}, 19 | {[]int{0, 1, 5, 8, 9, 10, 17, 17, 20}, 8, 22}, 20 | {[]int{0, 3, 5, 8, 9, 10, 17, 17, 20}, 8, 24}, 21 | } 22 | } 23 | 24 | func cutRodSolTestFunc(t *testing.T, cutRodSolFunc func([]int, int) int) { 25 | for _, tc := range getRodCuttingTestCases() { 26 | actual := cutRodSolFunc(tc.price, tc.length) 27 | if actual != tc.expected { 28 | t.Errorf("expected: %d, got: %d", tc.expected, actual) 29 | } 30 | } 31 | } 32 | 33 | func TestCutRodRec(t *testing.T) { 34 | cutRodSolTestFunc(t, dynamic.CutRodRec) 35 | } 36 | 37 | func TestCutRodDp(t *testing.T) { 38 | cutRodSolTestFunc(t, dynamic.CutRodDp) 39 | } 40 | -------------------------------------------------------------------------------- /dynamic/tilingproblem.go: -------------------------------------------------------------------------------- 1 | // tilingproblem.go 2 | // description: Solves the Tiling Problem using dynamic programming 3 | // reference: https://en.wikipedia.org/wiki/Tiling_problem 4 | // time complexity: O(n) 5 | // space complexity: O(n) 6 | 7 | package dynamic 8 | 9 | // TilingProblem returns the number of ways to tile a 2xN grid using 2x1 dominoes 10 | func TilingProblem(n int) int { 11 | if n <= 1 { 12 | return 1 13 | } 14 | dp := make([]int, n+1) 15 | dp[0] = 1 16 | dp[1] = 1 17 | 18 | for i := 2; i <= n; i++ { 19 | dp[i] = dp[i-1] + dp[i-2] 20 | } 21 | return dp[n] 22 | } 23 | -------------------------------------------------------------------------------- /dynamic/tilingproblem_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TheAlgorithms/Go/dynamic" 7 | ) 8 | 9 | type testCaseTilingProblem struct { 10 | n int 11 | expected int 12 | } 13 | 14 | func getTilingProblemTestCases() []testCaseTilingProblem { 15 | return []testCaseTilingProblem{ 16 | {1, 1}, // Base case: 1 way to tile a 2x1 grid 17 | {2, 2}, // 2 ways to tile a 2x2 grid 18 | {3, 3}, // 3 ways to tile a 2x3 grid 19 | {4, 5}, // 5 ways to tile a 2x4 grid 20 | {5, 8}, // 8 ways to tile a 2x5 grid 21 | {6, 13}, // 13 ways to tile a 2x6 grid 22 | {10, 89}, // 89 ways to tile a 2x10 grid 23 | {0, 1}, // Edge case: 1 way to tile a 2x0 grid (no tiles) 24 | {7, 21}, // 21 ways to tile a 2x7 grid 25 | {8, 34}, // 34 ways to tile a 2x8 grid 26 | } 27 | } 28 | 29 | func TestTilingProblem(t *testing.T) { 30 | t.Run("Tiling Problem test cases", func(t *testing.T) { 31 | for _, tc := range getTilingProblemTestCases() { 32 | actual := dynamic.TilingProblem(tc.n) 33 | if actual != tc.expected { 34 | t.Errorf("TilingProblem(%d) = %d; expected %d", tc.n, actual, tc.expected) 35 | } 36 | } 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /dynamic/traprainwater_test.go: -------------------------------------------------------------------------------- 1 | package dynamic_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/TheAlgorithms/Go/dynamic" 8 | ) 9 | 10 | func TestTrapRainWater(t *testing.T) { 11 | heights := [][]int{ 12 | {}, 13 | {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1}, 14 | {4, 2, 0, 3, 2, 5}, 15 | {3, 1, 2, 4, 0, 1, 3, 2, 4}, 16 | } 17 | 18 | expectedResults := []int{ 19 | 0, 20 | 6, 21 | 9, 22 | 13, 23 | } 24 | 25 | for i, height := range heights { 26 | expected := expectedResults[i] 27 | t.Run(fmt.Sprintf("Case %d", i+1), func(t *testing.T) { 28 | result := dynamic.TrapRainWater(height) 29 | if result != expected { 30 | t.Errorf("Expected %d, but got %d", expected, result) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dynamic/uniquepaths.go: -------------------------------------------------------------------------------- 1 | // See https://leetcode.com/problems/unique-paths/ 2 | // time complexity: O(m*n) where m and n are the dimensions of the grid 3 | // space complexity: O(m*n) where m and n are the dimensions of the grid 4 | // author: Rares Mateizer (https://github.com/rares985) 5 | package dynamic 6 | 7 | // UniquePaths implements the solution to the "Unique Paths" problem 8 | func UniquePaths(m, n int) int { 9 | if m <= 0 || n <= 0 { 10 | return 0 11 | } 12 | 13 | grid := make([][]int, m) 14 | for i := range grid { 15 | grid[i] = make([]int, n) 16 | } 17 | 18 | for i := 0; i < m; i++ { 19 | grid[i][0] = 1 20 | } 21 | 22 | for j := 0; j < n; j++ { 23 | grid[0][j] = 1 24 | } 25 | 26 | for i := 1; i < m; i++ { 27 | for j := 1; j < n; j++ { 28 | grid[i][j] = grid[i-1][j] + grid[i][j-1] 29 | } 30 | } 31 | 32 | return grid[m-1][n-1] 33 | } 34 | -------------------------------------------------------------------------------- /dynamic/uniquepaths_test.go: -------------------------------------------------------------------------------- 1 | package dynamic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestUniquePaths(t *testing.T) { 8 | testCases := map[string]struct { 9 | m int 10 | n int 11 | want int 12 | }{ 13 | "negative sizes": {-1, -1, 0}, 14 | "empty matrix both dimensions": {0, 0, 0}, 15 | "empty matrix one dimension": {0, 1, 0}, 16 | "one element": {1, 1, 1}, 17 | "small matrix": {2, 2, 2}, 18 | "stress test": {1000, 1000, 2874513998398909184}, 19 | } 20 | 21 | for name, test := range testCases { 22 | t.Run(name, func(t *testing.T) { 23 | if got := UniquePaths(test.m, test.n); got != test.want { 24 | t.Errorf("UniquePaths(%v, %v) = %v, want %v", test.m, test.n, got, test.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dynamic/wildcardmatching.go: -------------------------------------------------------------------------------- 1 | // wildcardmatching.go 2 | // description: Solves the Wildcard Matching problem using dynamic programming 3 | // reference: https://en.wikipedia.org/wiki/Wildcard_matching 4 | // time complexity: O(m*n) 5 | // space complexity: O(m*n) 6 | 7 | package dynamic 8 | 9 | // IsMatch checks if the string `s` matches the wildcard pattern `p` 10 | func IsMatch(s, p string) bool { 11 | dp := make([][]bool, len(s)+1) 12 | for i := range dp { 13 | dp[i] = make([]bool, len(p)+1) 14 | } 15 | 16 | dp[0][0] = true 17 | for j := 1; j <= len(p); j++ { 18 | if p[j-1] == '*' { 19 | dp[0][j] = dp[0][j-1] 20 | } 21 | } 22 | 23 | for i := 1; i <= len(s); i++ { 24 | for j := 1; j <= len(p); j++ { 25 | if p[j-1] == s[i-1] || p[j-1] == '?' { 26 | dp[i][j] = dp[i-1][j-1] 27 | } else if p[j-1] == '*' { 28 | dp[i][j] = dp[i-1][j] || dp[i][j-1] 29 | } 30 | } 31 | } 32 | return dp[len(s)][len(p)] 33 | } 34 | -------------------------------------------------------------------------------- /dynamic/wordbreak.go: -------------------------------------------------------------------------------- 1 | // wordbreak.go 2 | // description: Solves the Word Break Problem using dynamic programming 3 | // reference: https://en.wikipedia.org/wiki/Word_break_problem 4 | // time complexity: O(n^2) 5 | // space complexity: O(n) 6 | 7 | package dynamic 8 | 9 | // WordBreak checks if the input string can be segmented into words from a dictionary 10 | func WordBreak(s string, wordDict []string) bool { 11 | wordSet := make(map[string]bool) 12 | for _, word := range wordDict { 13 | wordSet[word] = true 14 | } 15 | 16 | dp := make([]bool, len(s)+1) 17 | dp[0] = true 18 | 19 | for i := 1; i <= len(s); i++ { 20 | for j := 0; j < i; j++ { 21 | if dp[j] && wordSet[s[j:i]] { 22 | dp[i] = true 23 | break 24 | } 25 | } 26 | } 27 | return dp[len(s)] 28 | } 29 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TheAlgorithms/Go 2 | 3 | go 1.19 4 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheAlgorithms/Go/5ba447ec5ff3d1213de65b92e726ee74c5d5cc19/go.sum -------------------------------------------------------------------------------- /graph/coloring/backtracking_test.go: -------------------------------------------------------------------------------- 1 | // This file provides tests for coloring using backtracking. 2 | // Author(s): [Shivam](https://github.com/Shivam010) 3 | 4 | package coloring_test 5 | 6 | import ( 7 | "strconv" 8 | "testing" 9 | ) 10 | 11 | func TestGraphColorUsingBacktracking(t *testing.T) { 12 | for i, tt := range getTestGraphs() { 13 | t.Run(strconv.Itoa(i), func(t *testing.T) { 14 | colorsOfVertices, colors := tt.Graph.ColorUsingBacktracking() 15 | if colors != tt.ColorsUsed { 16 | t.Errorf("ColorUsingBacktracking() return more number of colors: %v, want %v colors", colors, tt.ColorsUsed) 17 | } 18 | // check colors 19 | if err := tt.Graph.ValidateColorsOfVertex(colorsOfVertices); err != nil { 20 | t.Errorf("ColorUsingBacktracking() assigned colors are wrong, error = %v", err) 21 | } 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /graph/coloring/bfs_test.go: -------------------------------------------------------------------------------- 1 | // This file provides tests for coloring using BFS. 2 | // Author(s): [Shivam](https://github.com/Shivam010) 3 | 4 | package coloring_test 5 | 6 | import ( 7 | "strconv" 8 | "testing" 9 | ) 10 | 11 | func TestGraphColorUsingBFS(t *testing.T) { 12 | for i, tt := range getTestGraphs() { 13 | t.Run(strconv.Itoa(i), func(t *testing.T) { 14 | colorsOfVertices, colors := tt.Graph.ColorUsingBFS() 15 | if colors != tt.ColorsUsed { 16 | t.Errorf("ColorUsingBFS() return more number of colors: %v, want %v colors", colors, tt.ColorsUsed) 17 | } 18 | // check colors 19 | if err := tt.Graph.ValidateColorsOfVertex(colorsOfVertices); err != nil { 20 | t.Errorf("ColorUsingBFS() assigned colors are wrong, error = %v", err) 21 | } 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /graph/coloring/bipartite_test.go: -------------------------------------------------------------------------------- 1 | package coloring 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var testCases = []struct { 8 | name string 9 | N int 10 | isBipartite bool 11 | edges [][]int 12 | }{ 13 | { 14 | "basic true", 2, true, 15 | [][]int{{1, 0}}, 16 | }, 17 | { 18 | "basic false", 3, false, 19 | [][]int{{0, 1}, {1, 2}, {2, 0}}, 20 | }, 21 | } 22 | 23 | func TestBipartite(t *testing.T) { 24 | for _, tc := range testCases { 25 | t.Run(tc.name, func(t *testing.T) { 26 | actual := BipartiteCheck(tc.N, tc.edges) 27 | if tc.isBipartite != actual { 28 | t.Errorf("failed %s: %v", tc.name, tc.edges) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /graph/coloring/doc.go: -------------------------------------------------------------------------------- 1 | // Package coloring provides implementation of different graph coloring 2 | // algorithms, e.g. coloring using BFS, using Backtracking, using greedy 3 | // approach. 4 | // Author(s): [Shivam](https://github.com/Shivam010) 5 | package coloring 6 | -------------------------------------------------------------------------------- /graph/coloring/greedy_test.go: -------------------------------------------------------------------------------- 1 | // This file provides tests for coloring using Greedy approach. 2 | // Author(s): [Shivam](https://github.com/Shivam010) 3 | 4 | package coloring_test 5 | 6 | import ( 7 | "strconv" 8 | "testing" 9 | ) 10 | 11 | func TestGraphColorUsingGreedyApproach(t *testing.T) { 12 | for i, tt := range getTestGraphs() { 13 | t.Run(strconv.Itoa(i), func(t *testing.T) { 14 | colorsOfVertices, colors := tt.Graph.ColorUsingGreedyApproach() 15 | if colors != tt.ColorsUsed { 16 | t.Errorf("ColorUsingGreedyApproach() return more number of colors: %v, want %v colors", colors, tt.ColorsUsed) 17 | } 18 | // check colors 19 | if err := tt.Graph.ValidateColorsOfVertex(colorsOfVertices); err != nil { 20 | t.Errorf("ColorUsingGreedyApproach() assigned colors are wrong, error = %v", err) 21 | } 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /graph/dijkstra_test.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var tc_dijkstra = []struct { 8 | name string 9 | edges [][]int 10 | node0 int 11 | node1 int 12 | expected int 13 | }{ 14 | { 15 | "straight line graph", 16 | [][]int{{0, 1, 5}, {1, 2, 2}}, 17 | 0, 2, 7, 18 | }, 19 | { 20 | "unconnected node", 21 | [][]int{{0, 1, 5}}, 22 | 0, 2, -1, 23 | }, 24 | { 25 | "double paths", 26 | [][]int{{0, 1, 5}, {1, 3, 5}, {0, 2, 5}, {2, 3, 4}}, 27 | 0, 3, 9, 28 | }, 29 | { 30 | "double paths extended", 31 | [][]int{{0, 1, 5}, {1, 3, 5}, {0, 2, 5}, {2, 3, 4}, {3, 4, 1}}, 32 | 0, 4, 10, 33 | }, 34 | } 35 | 36 | func TestDijkstra(t *testing.T) { 37 | for _, tc := range tc_dijkstra { 38 | t.Run(tc.name, func(t *testing.T) { 39 | var graph Graph 40 | for _, edge := range tc.edges { 41 | graph.AddWeightedEdge(edge[0], edge[1], edge[2]) 42 | } 43 | 44 | actual, _ := graph.Dijkstra(tc.node0, tc.node1) 45 | if actual != tc.expected { 46 | t.Errorf("expected %d, got %d, from node %d to %d, with %v", 47 | tc.expected, actual, tc.node0, tc.node1, tc.edges) 48 | } 49 | }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /graph/doc.go: -------------------------------------------------------------------------------- 1 | // Package graph demonstrates Graph search algorithms 2 | // reference: https://en.wikipedia.org/wiki/Tree_traversal 3 | package graph 4 | -------------------------------------------------------------------------------- /graph/topological_test.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var testCases = []struct { 8 | name string 9 | N int 10 | constraints [][]int 11 | }{ 12 | { 13 | "basic test", 2, 14 | [][]int{{1, 0}}, 15 | }, 16 | { 17 | "double path", 7, 18 | [][]int{ 19 | {0, 1}, {1, 3}, {3, 5}, 20 | {0, 2}, {2, 4}, {4, 6}}, 21 | }, 22 | { 23 | "star shape", 7, 24 | [][]int{ 25 | {0, 1}, {0, 3}, {0, 5}, 26 | {0, 2}, {0, 4}, {0, 6}}, 27 | }, 28 | { 29 | "tree shape", 7, 30 | [][]int{ 31 | {0, 1}, {1, 3}, {1, 5}, 32 | {0, 2}, {2, 4}, {2, 6}}, 33 | }, 34 | } 35 | 36 | func TestTopological(t *testing.T) { 37 | for _, tc := range testCases { 38 | t.Run(tc.name, func(t *testing.T) { 39 | actual := Topological(tc.N, tc.constraints) 40 | 41 | visited := make([]bool, tc.N) 42 | positions := make([]int, tc.N) 43 | for i := 0; i < tc.N; i++ { 44 | positions[actual[i]] = i 45 | visited[actual[i]] = true 46 | } 47 | for _, v := range visited { 48 | if !v { 49 | t.Errorf("nodes not all visited, %v", visited) 50 | } 51 | } 52 | for _, c := range tc.constraints { 53 | if positions[c[0]] > positions[c[1]] { 54 | t.Errorf("%v dun satisfy %v", actual, c) 55 | } 56 | } 57 | }) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /hashing/doc.go: -------------------------------------------------------------------------------- 1 | // Package hashing containing different implementation of certain hashing 2 | package hashing 3 | -------------------------------------------------------------------------------- /hashing/hashing_test.go: -------------------------------------------------------------------------------- 1 | // Empty test file to keep track of all the tests for the algorithms. 2 | 3 | package hashing 4 | -------------------------------------------------------------------------------- /math/abs.go: -------------------------------------------------------------------------------- 1 | // abs.go 2 | // description: Absolute value 3 | // details: 4 | // In mathematics, the absolute value or modulus of a real number x, denoted |x|, is the non-negative value of x without regard to its sign. [Absolute value](https://en.wikipedia.org/wiki/Average#Arithmetic_mean) 5 | // author(s) [red_byte](https://github.com/i-redbyte) 6 | // see abs_test.go 7 | 8 | package math 9 | 10 | // Abs returns absolute value 11 | func Abs(n int) int { 12 | if n < 0 { 13 | return -n 14 | } 15 | return n 16 | } 17 | -------------------------------------------------------------------------------- /math/abs_test.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "github.com/TheAlgorithms/Go/math/binary" 5 | "math" 6 | "testing" 7 | ) 8 | 9 | func TestAbs(t *testing.T) { 10 | tests := getTests() 11 | for _, test := range tests { 12 | t.Run(test.name, func(t *testing.T) { 13 | if got := Abs(test.n); got != test.want { 14 | t.Errorf("Abs() = %v, want %v", got, test.want) 15 | } 16 | }) 17 | } 18 | } 19 | 20 | func getTests() []struct { 21 | name string 22 | n int 23 | want int 24 | } { 25 | tests := []struct { 26 | name string 27 | n int 28 | want int 29 | }{ 30 | {"-1 = |1| ", -1, 1}, 31 | {"-255 = |255| ", -255, 255}, 32 | {"0 = |0| ", 0, 0}, 33 | {"5 = |5| ", 5, 5}, 34 | {"-5 = |5| ", -5, 5}, 35 | {"-98368972 = |98368972| ", -98368972, 98368972}, 36 | } 37 | return tests 38 | } 39 | 40 | func BenchmarkSimpleAbs(b *testing.B) { 41 | for i := 0; i < b.N; i++ { 42 | Abs(-1024) 43 | } 44 | } 45 | func BenchmarkBinaryAbs32(b *testing.B) { 46 | for i := 0; i < b.N; i++ { 47 | binary.Abs(32, -1024) 48 | } 49 | } 50 | 51 | func BenchmarkBinaryAbs64(b *testing.B) { 52 | for i := 0; i < b.N; i++ { 53 | binary.Abs(64, -1024) 54 | } 55 | } 56 | 57 | func BenchmarkStdLibAbs(b *testing.B) { 58 | for i := 0; i < b.N; i++ { 59 | math.Abs(-1024) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /math/aliquot_test.go: -------------------------------------------------------------------------------- 1 | // aliquotsum_test.go 2 | // description: Returns s(n) 3 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 4 | // see aliquotsum.go 5 | 6 | package math_test 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/TheAlgorithms/Go/math" 12 | ) 13 | 14 | func TestAliquotSum(t *testing.T) { 15 | var tests = []struct { 16 | name string 17 | n int 18 | expectedValue int 19 | expectedError error 20 | }{ 21 | {"n = 10", 10, 8, nil}, 22 | {"n = 11", 11, 1, nil}, 23 | {"n = 1", 1, 0, nil}, 24 | {"n = -1", -1, 0, math.ErrPosArgsOnly}, 25 | {"n = 0", 0, 0, math.ErrNonZeroArgsOnly}, 26 | } 27 | for _, test := range tests { 28 | t.Run(test.name, func(t *testing.T) { 29 | result, err := math.AliquotSum(test.n) 30 | if result != test.expectedValue || test.expectedError != err { 31 | t.Errorf("expected error: %s, got: %s; expected value: %v, got: %v", test.expectedError, err, test.expectedValue, result) 32 | } 33 | }) 34 | } 35 | } 36 | func BenchmarkAliquotSum(b *testing.B) { 37 | for i := 0; i < b.N; i++ { 38 | _, _ = math.AliquotSum(65536) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /math/aliquotsum.go: -------------------------------------------------------------------------------- 1 | // aliquotsum.go 2 | // description: Returns s(n) 3 | // details: 4 | // the aliquot sum s(n) of a positive integer n 5 | // is the sum of all proper divisors of n, 6 | // that is, all divisors of n other than n itself 7 | // wikipedia: https://en.wikipedia.org/wiki/Aliquot_sum 8 | // time complexity: O(n) 9 | // space complexity: O(1) 10 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 11 | // see aliquotsum_test.go 12 | 13 | package math 14 | 15 | // This function returns s(n) for given number 16 | func AliquotSum(n int) (int, error) { 17 | switch { 18 | case n < 0: 19 | return 0, ErrPosArgsOnly 20 | case n == 0: 21 | return 0, ErrNonZeroArgsOnly 22 | default: 23 | var sum int 24 | for i := 1; i <= n/2; i++ { 25 | if n%i == 0 { 26 | sum += i 27 | } 28 | } 29 | return sum, nil 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /math/armstrong/isarmstrong.go: -------------------------------------------------------------------------------- 1 | // isarmstrong.go 2 | // description: Checks if the given number is armstrong number or not 3 | // details: An Armstrong number is a n-digit number that is equal to the sum of each of its digits taken to the nth power. 4 | // time complexity: O(log(n)) 5 | // space complexity: O(1) 6 | // ref: https://mathlair.allfunandgames.ca/armstrong.php 7 | // author: Kavitha J 8 | 9 | package armstrong 10 | 11 | import ( 12 | "math" 13 | "strconv" 14 | ) 15 | 16 | func IsArmstrong(number int) bool { 17 | var rightMost int 18 | var sum int = 0 19 | var tempNum int = number 20 | 21 | // to get the number of digits in the number 22 | length := float64(len(strconv.Itoa(number))) 23 | 24 | // get the right most digit and break the loop once all digits are iterated 25 | for tempNum > 0 { 26 | rightMost = tempNum % 10 27 | sum += int(math.Pow(float64(rightMost), length)) 28 | 29 | // update the input digit minus the processed rightMost 30 | tempNum /= 10 31 | } 32 | 33 | return number == sum 34 | } 35 | -------------------------------------------------------------------------------- /math/armstrong/isarmstrong_test.go: -------------------------------------------------------------------------------- 1 | // isarmstrong_test.go 2 | 3 | package armstrong 4 | 5 | import "testing" 6 | 7 | var testCases = []struct { 8 | name string // test description 9 | input int // user input 10 | expected bool // expected return 11 | }{ 12 | { 13 | "negative number: Not an armstrong number", 14 | -140, 15 | false, 16 | }, 17 | { 18 | "positive number: Not an armstrong number", 19 | 23, 20 | false, 21 | }, 22 | { 23 | "smallest armstrong number", 24 | 0, 25 | true, 26 | }, 27 | { 28 | "smallest armstrong number with more than one digit", 29 | 153, 30 | true, 31 | }, 32 | { 33 | "random armstrong number", 34 | 407, 35 | true, 36 | }, 37 | { 38 | "random armstrong number", 39 | 9474, 40 | true, 41 | }, 42 | } 43 | 44 | func TestIsArmstrong(t *testing.T) { 45 | for _, test := range testCases { 46 | t.Run(test.name, func(t *testing.T) { 47 | funcResult := IsArmstrong(test.input) 48 | if test.expected != funcResult { 49 | t.Errorf("Expected answer '%t' for the number '%d' but answer given was %t", test.expected, test.input, funcResult) 50 | } 51 | }) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /math/binary/abs.go: -------------------------------------------------------------------------------- 1 | // abs.go 2 | // description: returns absolute value using binary operation 3 | // time complexity: O(1) 4 | // space complexity: O(1) 5 | 6 | package binary 7 | 8 | // Abs returns absolute value using binary operation 9 | // Principle of operation: 10 | // 1) Get the mask by right shift by the base 11 | // 2) Base is the size of an integer variable in bits, for example, for int32 it will be 32, for int64 it will be 64 12 | // 3) For negative numbers, above step sets mask as 1 1 1 1 1 1 1 1 and 0 0 0 0 0 0 0 0 for positive numbers. 13 | // 4) Add the mask to the given number. 14 | // 5) XOR of mask + n and mask gives the absolute value. 15 | func Abs(base, n int) int { 16 | m := n >> (base - 1) 17 | return (n + m) ^ m 18 | } 19 | -------------------------------------------------------------------------------- /math/binary/abs_test.go: -------------------------------------------------------------------------------- 1 | package binary 2 | 3 | import "testing" 4 | 5 | func TestAbs(t *testing.T) { 6 | tests := getAbsTests() 7 | for _, test := range tests { 8 | t.Run(test.name, func(t *testing.T) { 9 | if got := Abs(test.base, test.n); got != test.want { 10 | t.Errorf("Abs() = %v, want %v", got, test.want) 11 | } 12 | }) 13 | } 14 | } 15 | 16 | func getAbsTests() []struct { 17 | name string 18 | base int 19 | n int 20 | want int 21 | } { 22 | tests := []struct { 23 | name string 24 | base int 25 | n int 26 | want int 27 | }{ 28 | {"-1 = |1| ", 32, -1, 1}, 29 | {"-255 = |255| ", 32, -255, 255}, 30 | {"0 = |0| ", 64, 0, 0}, 31 | {"5 = |5| ", 16, 5, 5}, 32 | {"-5 = |5| ", 32, -5, 5}, 33 | {"-98368972 = |98368972| ", 64, -98368972, 98368972}, 34 | {"-110298368972 = |110298368972| ", 64, -98368972, 98368972}, 35 | } 36 | return tests 37 | } 38 | -------------------------------------------------------------------------------- /math/binary/arithmeticmean.go: -------------------------------------------------------------------------------- 1 | // arithmeticmean.go 2 | // description: Arithmetic mean 3 | // details: 4 | // The most common type of average is the arithmetic mean. If n numbers are given, each number denoted by ai (where i = 1,2, ..., n), the arithmetic mean is the sum of the as divided by n or - [Arithmetic mean](https://en.wikipedia.org/wiki/Average#Arithmetic_mean) 5 | // time complexity: O(1) 6 | // space complexity: O(1) 7 | // author(s) [red_byte](https://github.com/i-redbyte) 8 | // see arithmeticmean_test.go 9 | 10 | // Package binary describes algorithms that use binary operations for different calculations. 11 | package binary 12 | 13 | // MeanUsingAndXor This function finds arithmetic mean using "AND" and "XOR" operations 14 | func MeanUsingAndXor(a int, b int) int { 15 | return ((a ^ b) >> 1) + (a & b) 16 | } 17 | 18 | // MeanUsingRightShift This function finds arithmetic mean using right shift 19 | func MeanUsingRightShift(a int, b int) int { 20 | return (a + b) >> 1 21 | } 22 | -------------------------------------------------------------------------------- /math/binary/bitcounter.go: -------------------------------------------------------------------------------- 1 | // bitcounter.go 2 | // description: Counts the number of set bits in a number 3 | // details: 4 | // For unsigned integer number N, return the number of bits set to 1 - [Bit numbering](https://en.wikipedia.org/wiki/Bit_numbering) 5 | // time complexity: O(log(n)) 6 | // space complexity: O(1) 7 | // author(s) [red_byte](https://github.com/i-redbyte) 8 | // see bitcounter_test.go 9 | 10 | package binary 11 | 12 | // BitCounter - The function returns the number of set bits for an unsigned integer number 13 | func BitCounter(n uint) int { 14 | counter := 0 15 | for n != 0 { 16 | if n&1 == 1 { 17 | counter++ 18 | } 19 | n >>= 1 20 | } 21 | return counter 22 | } 23 | -------------------------------------------------------------------------------- /math/binary/bitcounter_test.go: -------------------------------------------------------------------------------- 1 | // bitcounter_test.go 2 | // description: Test for counts the number of set bits in a number 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see bitcounter.go 5 | 6 | package binary 7 | 8 | import "testing" 9 | 10 | func TestBitCounter(t *testing.T) { 11 | tests := []struct { 12 | name string 13 | number uint 14 | want int 15 | }{ 16 | {"Number of bits in a number 0", 0, 0}, 17 | {"Number of bits in a number 1", 1, 1}, 18 | {"Number of bits in a number 255", 255, 8}, 19 | {"Number of bits in a number 7", 7, 3}, 20 | {"Number of bits in a number 8", 8, 1}, 21 | {"Number of bits in a number 9223372036854775807", 9223372036854775807, 63}, 22 | {"Number of bits in a number 2147483647", 2147483647, 31}, 23 | {"Number of bits in a number 15", 15, 4}, 24 | {"Number of bits in a number 16", 16, 1}, 25 | } 26 | for _, test := range tests { 27 | t.Run(test.name, func(t *testing.T) { 28 | if got := BitCounter(test.number); got != test.want { 29 | t.Errorf("BitCounter() = %v, want %v", got, test.want) 30 | } 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /math/binary/fast_inverse_sqrt.go: -------------------------------------------------------------------------------- 1 | // Calculating the inverse square root 2 | // time complexity: O(1) 3 | // space complexity: O(1) 4 | // [See more](https://en.wikipedia.org/wiki/Fast_inverse_square_root) 5 | 6 | package binary 7 | 8 | import ( 9 | "math" 10 | ) 11 | 12 | // FastInverseSqrt assumes that argument is always positive, 13 | // and it does not deal with negative numbers. 14 | // The "magic" number 0x5f3759df is hex for 1597463007 in decimals. 15 | // The math.Float32bits is alias to *(*uint32)(unsafe.Pointer(&f)) 16 | // and math.Float32frombits is to *(*float32)(unsafe.Pointer(&b)). 17 | func FastInverseSqrt(number float32) float32 { 18 | var i uint32 19 | var y, x2 float32 20 | const threehalfs float32 = 1.5 21 | 22 | x2 = number * float32(0.5) 23 | y = number 24 | i = math.Float32bits(y) // evil floating point bit level hacking 25 | i = 0x5f3759df - (i >> 1) // magic number and bitshift hacking 26 | y = math.Float32frombits(i) 27 | 28 | y = y * (threehalfs - (x2 * y * y)) // 1st iteration of Newton's method 29 | y = y * (threehalfs - (x2 * y * y)) // 2nd iteration, this can be removed 30 | return y 31 | } 32 | -------------------------------------------------------------------------------- /math/binary/logarithm.go: -------------------------------------------------------------------------------- 1 | // author(s) [red_byte](https://github.com/i-redbyte) 2 | // time complexity: O(1) 3 | // space complexity: O(1) 4 | // see logarithm_test.go 5 | 6 | package binary 7 | 8 | // LogBase2 Finding the exponent of n = 2**x using bitwise operations (logarithm in base 2 of n) [See more](https://en.wikipedia.org/wiki/Logarithm) 9 | func LogBase2(n uint32) uint32 { 10 | base := [5]uint32{0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000} 11 | exponents := [5]uint32{1, 2, 4, 8, 16} 12 | var result uint32 13 | for i := 4; i >= 0; i-- { 14 | if n&base[i] != 0 { 15 | n >>= exponents[i] 16 | result |= exponents[i] 17 | } 18 | } 19 | return result 20 | } 21 | -------------------------------------------------------------------------------- /math/binary/logarithm_test.go: -------------------------------------------------------------------------------- 1 | // logarithm_test.go 2 | // description: Test for finding the exponent of n = 2**x using bitwise operations (logarithm in base 2 of n) 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see logarithm.go 5 | 6 | package binary 7 | 8 | import ( 9 | "math" 10 | "testing" 11 | ) 12 | 13 | func TestLogBase2(t *testing.T) { 14 | tests := []struct { 15 | name string 16 | n uint32 17 | want uint32 18 | }{ 19 | {"log2(1) = 0", 1, 0}, 20 | {"log2(2) = 1", 2, 1}, 21 | {"log2(4) = 2", 4, 2}, 22 | {"log2(8) = 3", 8, 3}, 23 | {"log2(16) = 4", 16, 4}, 24 | {"log2(32) = 5", 32, 5}, 25 | {"log2(64) = 6", 64, 6}, 26 | {"log2(128) = 7", 128, 7}, 27 | {"log2(256) = 8", 256, 8}, 28 | } 29 | for _, test := range tests { 30 | t.Run(test.name, func(t *testing.T) { 31 | if got := LogBase2(test.n); got != test.want { 32 | t.Errorf("LogBase2() = %v, want %v", got, test.want) 33 | } 34 | }) 35 | } 36 | } 37 | 38 | func BenchmarkBitwiseLogBase2(b *testing.B) { 39 | for i := 0; i < b.N; i++ { 40 | LogBase2(1024) 41 | } 42 | } 43 | 44 | func BenchmarkMathPAckageLogBase2(b *testing.B) { 45 | for i := 0; i < b.N; i++ { 46 | math.Log2(1024) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /math/binary/rbc.go: -------------------------------------------------------------------------------- 1 | // rbc.go 2 | // description: Reflected binary code (RBC) 3 | // details: 4 | // The reflected binary code (RBC), also known just as reflected binary (RB) or Gray code after Frank Gray, is an ordering of the binary numeral system such that two successive values differ in only one bit (binary digit). - [RBC](https://en.wikipedia.org/wiki/Gray_code) 5 | // time complexity: O(n) 6 | // space complexity: O(n) 7 | // author(s) [red_byte](https://github.com/i-redbyte) 8 | // see rbc_test.go 9 | 10 | package binary 11 | 12 | // SequenceGrayCode The function generates an "Gray code" sequence of length n 13 | func SequenceGrayCode(n uint) []uint { 14 | result := make([]uint, 0) 15 | var i uint 16 | for i = 0; i < 1<>1)) 18 | } 19 | return result 20 | } 21 | -------------------------------------------------------------------------------- /math/binary/reversebits.go: -------------------------------------------------------------------------------- 1 | // reversebits.go 2 | // description: Reverse bits 3 | // details: 4 | // Reverse the bits of an integer number 5 | // time complexity: O(log(n)) 6 | // space complexity: O(1) 7 | // author(s) [red_byte](https://github.com/i-redbyte) 8 | // see reversebits_test.go 9 | 10 | package binary 11 | 12 | // ReverseBits This function initialized the result by 0 (all bits 0) and process the given number starting 13 | // from its least significant bit. If the current bit is 1, set the corresponding most significant bit in the result 14 | // and finally move on to the next bit in the input number. 15 | // Repeat this till all its bits are processed. 16 | func ReverseBits(number uint) uint { 17 | result := uint(0) 18 | intSize := 31 19 | for number != 0 { 20 | result += (number & 1) << intSize 21 | number = number >> 1 22 | intSize -= 1 23 | } 24 | return result 25 | } 26 | -------------------------------------------------------------------------------- /math/binary/sqrt.go: -------------------------------------------------------------------------------- 1 | // sqrt.go 2 | // description: Square root calculation 3 | // details: 4 | // Calculating the square root using binary operations and a magic number 0x5f3759df [See more](https://en.wikipedia.org/wiki/Fast_inverse_square_root) 5 | // author(s) [red_byte](https://github.com/i-redbyte) 6 | // time complexity: O(1) 7 | // space complexity: O(1) 8 | // see sqrt_test.go 9 | 10 | package binary 11 | 12 | func Sqrt(n float32) float32 { return 1 / FastInverseSqrt(n) } 13 | -------------------------------------------------------------------------------- /math/binary/sqrt_test.go: -------------------------------------------------------------------------------- 1 | // sqrt_test.go 2 | // description: Test for square root calculation 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see sqrt.go 5 | 6 | package binary 7 | 8 | import ( 9 | "math" 10 | "testing" 11 | ) 12 | 13 | const epsilon = 0.001 14 | 15 | func TestSquareRootCalculation(t *testing.T) { 16 | tests := []struct { 17 | name string 18 | number float32 19 | want float64 20 | }{ 21 | {"sqrt(1)", 1, 1}, 22 | {"sqrt(9)", 9, 3}, 23 | {"sqrt(25)", 25, 5}, 24 | {"sqrt(121)", 121, 11}, 25 | {"sqrt(10000)", 10000, 100}, 26 | {"sqrt(169)", 169, 13}, 27 | {"sqrt(0)", 0, 0}, 28 | } 29 | for _, test := range tests { 30 | t.Run(test.name, func(t *testing.T) { 31 | got := Sqrt(test.number) 32 | delta := math.Abs(test.want - float64(got)) 33 | if delta > epsilon { 34 | t.Errorf("Sqrt() = %v, want %v delta %v", got, test.want, delta) 35 | } 36 | }) 37 | } 38 | } 39 | 40 | func BenchmarkSquareRootCalculation(b *testing.B) { 41 | for i := 0; i < b.N; i++ { 42 | Sqrt(225) 43 | } 44 | } 45 | 46 | func BenchmarkMathSqrt(b *testing.B) { 47 | for i := 0; i < b.N; i++ { 48 | math.Sqrt(225) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /math/binary/xorsearch.go: -------------------------------------------------------------------------------- 1 | // xorsearch.go 2 | // description: Find a missing number in a sequence 3 | // details: 4 | // Given an array A containing n distinct numbers in the range [0, n], return the only number in the range that is missing from the array. - [xor](https://en.wikipedia.org/wiki/Exclusive_or) 5 | // time complexity: O(n) 6 | // space complexity: O(1) 7 | // author(s) [red_byte](https://github.com/i-redbyte) 8 | // see xorsearch_test.go 9 | 10 | package binary 11 | 12 | // XorSearchMissingNumber This function finds a missing number in a sequence 13 | func XorSearchMissingNumber(a []int) int { 14 | n := len(a) 15 | result := len(a) 16 | for i := 0; i < n; i++ { 17 | result ^= i ^ a[i] 18 | } 19 | return result 20 | } 21 | -------------------------------------------------------------------------------- /math/binary/xorsearch_test.go: -------------------------------------------------------------------------------- 1 | // xorsearch_test.go 2 | // description: Test for Find a missing number in a sequence 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see xorsearch.go 5 | 6 | package binary 7 | 8 | import ( 9 | "testing" 10 | ) 11 | 12 | func TestXorSearchMissingNumber(t *testing.T) { 13 | var tests = []struct { 14 | name string 15 | a []int 16 | missing int 17 | }{ 18 | {"[3, 0, 1]/2", []int{3, 0, 1}, 2}, 19 | {"[0, 1, 3, 4, 5, 6, 7]/2", []int{0, 1, 3, 4, 5, 6, 7}, 2}, 20 | {"[0, 2, 3, 4, 5, 6, 7, 8, 9]/1", []int{0, 2, 3, 4, 5, 6, 7, 8, 9}, 1}, 21 | {"[0, 10, 9, 7, 2, 1, 4, 3, 5, 6]/8", []int{0, 10, 9, 7, 2, 1, 4, 3, 5, 6}, 8}, 22 | } 23 | 24 | for _, tv := range tests { 25 | t.Run(tv.name, func(t *testing.T) { 26 | result := XorSearchMissingNumber(tv.a) 27 | if result != tv.missing { 28 | t.Errorf("Wrong result! Expected:%d, returned:%d ", tv.missing, result) 29 | } 30 | }) 31 | } 32 | 33 | } 34 | 35 | func BenchmarkTestXorSearchMissingNumber(b *testing.B) { 36 | for i := 0; i < b.N; i++ { 37 | XorSearchMissingNumber([]int{0, 10, 9, 7, 2, 1, 4, 3, 5, 6}) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /math/binomialcoefficient.go: -------------------------------------------------------------------------------- 1 | // binomialcoefficient.go 2 | // description: Returns C(n, k) 3 | // details: 4 | // a binomial coefficient C(n,k) gives number ways 5 | // in which k objects can be chosen from n objects. 6 | // wikipedia: https://en.wikipedia.org/wiki/Binomial_coefficient 7 | // time complexity: O(k) or O(n-k) whichever is smaller (O(n) in worst case) 8 | // space complexity: O(1) 9 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 10 | // see binomialcoefficient_test.go 11 | 12 | package math 13 | 14 | import ( 15 | "errors" 16 | ) 17 | 18 | var ErrPosArgsOnly error = errors.New("arguments must be positive") 19 | 20 | // C is Binomial Coefficient function 21 | // This function returns C(n, k) for given n and k 22 | func Combinations(n int, k int) (int, error) { 23 | if n < 0 || k < 0 { 24 | return -1, ErrPosArgsOnly 25 | } 26 | if k > (n - k) { 27 | k = n - k 28 | } 29 | res := 1 30 | for i := 0; i < k; i++ { 31 | res *= (n - i) 32 | res /= (i + 1) 33 | } 34 | return res, nil 35 | } 36 | -------------------------------------------------------------------------------- /math/catalan/catalannumber.go: -------------------------------------------------------------------------------- 1 | // catalannumber.go 2 | // description: Returns the Catalan number 3 | // details: 4 | // In combinatorial mathematics, the Catalan numbers are a sequence of natural numbers that occur in various counting problems, often involving recursively defined objects. - [Catalan number](https://en.wikipedia.org/wiki/Catalan_number) 5 | // time complexity: O(n) 6 | // space complexity: O(1) 7 | // The input is the number of the Catalan number n, at the output we get the value of the number 8 | // author(s) [red_byte](https://github.com/i-redbyte) 9 | // see catalannumber_test.go 10 | 11 | package catalan 12 | 13 | import ( 14 | f "github.com/TheAlgorithms/Go/math/factorial" 15 | ) 16 | 17 | func factorial(n int) int { 18 | result, error := f.Iterative(n) 19 | if error != nil { 20 | panic(error) 21 | } 22 | return result 23 | } 24 | 25 | // CatalanNumber This function returns the `nth` Catalan number 26 | func CatalanNumber(n int) int { 27 | return factorial(n*2) / (factorial(n) * factorial(n+1)) 28 | } 29 | -------------------------------------------------------------------------------- /math/catalan/catalannumber_test.go: -------------------------------------------------------------------------------- 1 | // catalannumber_test.go 2 | // description: Test for returns the Catalan number 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see catalannumber.go 5 | 6 | package catalan 7 | 8 | import "testing" 9 | 10 | func TestCatalanNumber(t *testing.T) { 11 | tests := []struct { 12 | name string 13 | n int 14 | want int 15 | }{ 16 | {"zero Catalan number ", 0, 1}, 17 | {"second Catalan number ", 2, 2}, 18 | {"third Catalan number ", 3, 5}, 19 | {"fourth Catalan number ", 4, 14}, 20 | {"fifth Catalan number ", 5, 42}, 21 | {"sixth Catalan number ", 6, 132}, 22 | {"tenth Catalan number ", 10, 16796}, 23 | } 24 | for _, test := range tests { 25 | t.Run(test.name, func(t *testing.T) { 26 | if got := CatalanNumber(test.n); got != test.want { 27 | t.Errorf("CatalanNumber() = %v, want %v", got, test.want) 28 | } 29 | }) 30 | } 31 | } 32 | 33 | func BenchmarkCatalanNumber(b *testing.B) { 34 | for i := 0; i < b.N; i++ { 35 | CatalanNumber(10) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /math/checkisnumberpoweroftwo.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "math" 5 | ) 6 | 7 | // IsPowOfTwoUseLog This function checks if a number is a power of two using the logarithm. 8 | // The limiting degree can be from 0 to 63. 9 | // See alternatives in the binary package. 10 | func IsPowOfTwoUseLog(number float64) bool { 11 | if number == 0 || math.Round(number) == math.MaxInt64 { 12 | return false 13 | } 14 | log := math.Log2(number) 15 | return log == math.Round(log) 16 | } 17 | -------------------------------------------------------------------------------- /math/cos.go: -------------------------------------------------------------------------------- 1 | // author(s) [red_byte](https://github.com/i-redbyte) 2 | // see cos_test.go 3 | 4 | package math 5 | 6 | import "math" 7 | 8 | // Cos returns the cosine of the radian argument x. [See more](https://en.wikipedia.org/wiki/Sine_and_cosine) 9 | // [Based on the idea of Bhaskara approximation of cos(x)](https://math.stackexchange.com/questions/3886552/bhaskara-approximation-of-cosx) 10 | func Cos(x float64) float64 { 11 | tp := 1.0 / (2.0 * math.Pi) 12 | x *= tp 13 | x -= 0.25 + math.Floor(x+0.25) 14 | x *= 16.0 * (math.Abs(x) - 0.5) 15 | x += 0.225 * x * (math.Abs(x) - 1.0) //Extra precision 16 | return x 17 | } 18 | -------------------------------------------------------------------------------- /math/cos_test.go: -------------------------------------------------------------------------------- 1 | package math_test 2 | 3 | import ( 4 | algmath "github.com/TheAlgorithms/Go/math" 5 | stdmath "math" 6 | "testing" 7 | ) 8 | 9 | const epsilon = 0.001 10 | 11 | func TestCos(t *testing.T) { 12 | tests := []struct { 13 | name string 14 | n float64 15 | want float64 16 | }{ 17 | {"cos(0)", 0, 1}, 18 | {"cos(90)", 90, -0.447}, 19 | {"cos(180)", 180, -0.598}, 20 | {"cos(1)", 1, 0.540}, 21 | {"cos(π)", stdmath.Pi, -1}, 22 | {"cos(π/2)", stdmath.Pi / 2, 0}, 23 | } 24 | for _, test := range tests { 25 | t.Run(test.name, func(t *testing.T) { 26 | got := algmath.Cos(test.n) 27 | if stdmath.Abs(got-test.want) >= epsilon { 28 | t.Errorf("Cos() = %v, want %v", got, test.want) 29 | t.Errorf("MATH Cos() = %v", stdmath.Cos(test.n)) 30 | } 31 | }) 32 | } 33 | } 34 | 35 | func BenchmarkCos(b *testing.B) { 36 | for i := 0; i < b.N; i++ { 37 | algmath.Cos(180) 38 | } 39 | } 40 | 41 | // BenchmarkMathCos is slower because the standard library `math.Cos` calculates a more accurate value. 42 | func BenchmarkMathCos(b *testing.B) { 43 | for i := 0; i < b.N; i++ { 44 | stdmath.Cos(180) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /math/doc.go: -------------------------------------------------------------------------------- 1 | // Package math is a package that contains mathematical algorithms and its different implementations. 2 | package math 3 | -------------------------------------------------------------------------------- /math/eulertotient.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | // Phi is the Euler totient function. 4 | // This function computes the number of numbers less then n that are coprime with n. 5 | func Phi(n int64) int64 { 6 | result := n 7 | for i := int64(2); i*i <= n; i += 1 { 8 | if n%i == 0 { 9 | for { 10 | if n%i != 0 { 11 | break 12 | } 13 | n /= i 14 | } 15 | result -= result / i 16 | } 17 | } 18 | 19 | if n > 1 { 20 | result -= result / n 21 | } 22 | return result 23 | } 24 | -------------------------------------------------------------------------------- /math/eulertotient_test.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func getTestsForPhi() []struct { 8 | n int64 9 | expected int64 10 | } { 11 | var tests = []struct { 12 | n int64 13 | expected int64 14 | }{ 15 | {4, 2}, 16 | {5, 4}, 17 | {7, 6}, 18 | {10, 4}, 19 | {999, 648}, 20 | {1000, 400}, 21 | {1000000, 400000}, 22 | {999999, 466560}, 23 | {999999999999878, 473684210526240}, 24 | } 25 | return tests 26 | } 27 | 28 | func TestPhi(t *testing.T) { 29 | 30 | tests := getTestsForPhi() 31 | for _, test := range tests { 32 | result := Phi(test.n) 33 | t.Log(test.n, " ", result) 34 | if result != test.expected { 35 | t.Errorf("Wrong result! Expected:%v, returned:%v ", test.expected, result) 36 | } 37 | } 38 | } 39 | 40 | func BenchmarkPhi(b *testing.B) { 41 | for i := 0; i < b.N; i++ { 42 | Phi(65536) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /math/gcd/extended.go: -------------------------------------------------------------------------------- 1 | // extended.go 2 | // description: Implementation of Extended GCD Algorithm 3 | // details: 4 | // A simple implementation of Extended GCD algorithm, that returns GCD, a and b 5 | // which solves ax + by = gcd(a, b) 6 | // time complexity: O(log(min(a, b))) where a and b are the two numbers 7 | // space complexity: O(log(min(a, b))) where a and b are the two numbers 8 | // author(s) [Taj](https://github.com/tjgurwara99) 9 | // see extended_test.go 10 | 11 | package gcd 12 | 13 | // Extended simple extended gcd 14 | func Extended(a, b int64) (int64, int64, int64) { 15 | if a == 0 { 16 | return b, 0, 1 17 | } 18 | gcd, xPrime, yPrime := Extended(b%a, a) 19 | return gcd, yPrime - (b/a)*xPrime, xPrime 20 | } 21 | -------------------------------------------------------------------------------- /math/gcd/extended_test.go: -------------------------------------------------------------------------------- 1 | // extended_test.go 2 | // description: Test for Extended GCD algorithm in extended.go 3 | // author(s) [Taj](https://github.com/tjgurwara99) 4 | // see extended.go 5 | 6 | package gcd 7 | 8 | import "testing" 9 | 10 | func TestExtended(t *testing.T) { 11 | var testCasesExtended = []struct { 12 | name string 13 | a int64 14 | b int64 15 | gcd int64 16 | x int64 17 | y int64 18 | }{ 19 | {"gcd of 30 and 50", 30, 50, 10, 2, -1}, 20 | } 21 | for _, tc := range testCasesExtended { 22 | t.Run(tc.name, func(t *testing.T) { 23 | gcd, x, y := Extended(tc.a, tc.b) 24 | if gcd != tc.gcd && x != tc.x && y != tc.y { 25 | t.Fatalf("Expected values:\n\tGCD: Expected %v Returned %v,\n\tx: Expected %v Returned %v\n\ty: Expected %v Returned %v", tc.gcd, gcd, tc.x, x, tc.y, y) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /math/gcd/extendedgcd.go: -------------------------------------------------------------------------------- 1 | // extendedgcd.go 2 | // description: Implementation of Extended GCD Algorithm 3 | // time complexity: O(log(min(a, b))) where a and b are the two numbers 4 | // space complexity: O(log(min(a, b))) where a and b are the two numbers 5 | 6 | package gcd 7 | 8 | // ExtendedRecursive finds and returns gcd(a, b), x, y satisfying a*x + b*y = gcd(a, b). 9 | func ExtendedRecursive(a, b int64) (int64, int64, int64) { 10 | if b > 0 { 11 | d, y, x := ExtendedRecursive(b, a%b) 12 | y -= (a / b) * x 13 | return d, x, y 14 | } 15 | 16 | return a, 1, 0 17 | } 18 | -------------------------------------------------------------------------------- /math/gcd/extendedgcditerative.go: -------------------------------------------------------------------------------- 1 | package gcd 2 | 3 | // ExtendedIterative finds and returns gcd(a, b), x, y satisfying a*x + b*y = gcd(a, b). 4 | func ExtendedIterative(a, b int64) (int64, int64, int64) { 5 | var u, y, v, x int64 = 1, 1, 0, 0 6 | for a > 0 { 7 | var q int64 = b / a 8 | x, u = u, x-q*u 9 | y, v = v, y-q*v 10 | b, a = a, b-q*a 11 | } 12 | return b, x, y 13 | } 14 | -------------------------------------------------------------------------------- /math/gcd/gcd.go: -------------------------------------------------------------------------------- 1 | // time complexity: O(log(min(a, b))) where a and b are the two numbers 2 | // space complexity: O(1) 3 | 4 | package gcd 5 | 6 | // Recursive finds and returns the greatest common divisor of a given integer. 7 | func Recursive(a, b int64) int64 { 8 | if b == 0 { 9 | return a 10 | } 11 | return Recursive(b, a%b) 12 | } 13 | -------------------------------------------------------------------------------- /math/gcd/gcd_test.go: -------------------------------------------------------------------------------- 1 | package gcd 2 | 3 | import "testing" 4 | 5 | type testFunction func(int64, int64) int64 6 | 7 | var testCases = []struct { 8 | name string 9 | a int64 10 | b int64 11 | output int64 12 | }{ 13 | {"gcd of 10 and 0", 10, 0, 10}, 14 | {"gcd of 98 and 56", 98, 56, 14}, 15 | {"gcd of 0 and 10", 0, 10, 10}, 16 | } 17 | 18 | func TemplateTestGCD(t *testing.T, f testFunction) { 19 | for _, tc := range testCases { 20 | t.Run(tc.name, func(t *testing.T) { 21 | actual := f(tc.a, tc.b) 22 | if actual != tc.output { 23 | t.Errorf("Expected GCD of %d and %d to be: %v, but got: %d", tc.a, tc.b, tc.output, actual) 24 | } 25 | }) 26 | } 27 | } 28 | 29 | func TestGCDRecursive(t *testing.T) { 30 | TemplateTestGCD(t, Recursive) 31 | } 32 | 33 | func TestGCDIterative(t *testing.T) { 34 | TemplateTestGCD(t, Iterative) 35 | } 36 | 37 | func TemplateBenchmarkGCD(b *testing.B, f testFunction) { 38 | for i := 0; i < b.N; i++ { 39 | f(98, 56) 40 | } 41 | } 42 | 43 | func BenchmarkGCDRecursive(b *testing.B) { 44 | TemplateBenchmarkGCD(b, Recursive) 45 | } 46 | 47 | func BenchmarkGCDIterative(b *testing.B) { 48 | TemplateBenchmarkGCD(b, Iterative) 49 | } 50 | -------------------------------------------------------------------------------- /math/gcd/gcditerative.go: -------------------------------------------------------------------------------- 1 | // time complexity: O(log(min(a, b))) where a and b are the two numbers 2 | // space complexity: O(1) 3 | 4 | package gcd 5 | 6 | // Iterative Faster iterative version of GcdRecursive without holding up too much of the stack 7 | func Iterative(a, b int64) int64 { 8 | for b != 0 { 9 | a, b = b, a%b 10 | } 11 | return a 12 | } 13 | -------------------------------------------------------------------------------- /math/geometry/distance.go: -------------------------------------------------------------------------------- 1 | // distance.go 2 | // Find Euclidean distance between two points 3 | // time complexity: O(n) where n is the number of dimensions 4 | // space complexity: O(1) 5 | // author(s) [Chetan Patil](https://github.com/Chetan07j) 6 | 7 | // Package geometry contains geometric algorithms 8 | package geometry 9 | 10 | import ( 11 | "errors" 12 | "math" 13 | ) 14 | 15 | // EuclideanPoint defines a point with x and y coordinates. 16 | type EuclideanPoint []float64 17 | 18 | var ErrDimMismatch = errors.New("mismatched dimensions") 19 | 20 | // EuclideanDistance returns the Euclidean distance between points in 21 | // any `n` dimensional Euclidean space. 22 | func EuclideanDistance(p1 EuclideanPoint, p2 EuclideanPoint) (float64, error) { 23 | n := len(p1) 24 | 25 | if len(p2) != n { 26 | return -1, ErrDimMismatch 27 | } 28 | 29 | var total float64 = 0 30 | 31 | for i, x_i := range p1 { 32 | // using Abs since the value could be negative but we require the magnitude 33 | diff := math.Abs(x_i - p2[i]) 34 | total += diff * diff 35 | } 36 | 37 | return math.Sqrt(total), nil 38 | } 39 | -------------------------------------------------------------------------------- /math/isautomorphic.go: -------------------------------------------------------------------------------- 1 | // isautomorphic.go 2 | // description: Checks whether a whole number integer is Automorphic or not. If number < 0 then returns false. 3 | // details: 4 | // In mathematics, a number n is said to be a Automorphic number if the square of n ends in the same digits as n itself. 5 | // ref: (https://en.wikipedia.org/wiki/Automorphic_number) 6 | // time complexity: O(log10(N)) 7 | // space complexity: O(1) 8 | // author: [SilverDragonOfR](https://github.com/SilverDragonOfR) 9 | 10 | package math 11 | 12 | import ( 13 | "github.com/TheAlgorithms/Go/constraints" 14 | ) 15 | 16 | func IsAutomorphic[T constraints.Integer](n T) bool { 17 | // handling the negetive number case 18 | if n < 0 { 19 | return false 20 | } 21 | 22 | n_sq := n * n 23 | for n > 0 { 24 | if (n % 10) != (n_sq % 10) { 25 | return false 26 | } 27 | n /= 10 28 | n_sq /= 10 29 | } 30 | 31 | return true 32 | } 33 | -------------------------------------------------------------------------------- /math/isautomorphic_test.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var testCases = []struct { 8 | name string 9 | input int 10 | expected bool 11 | }{ 12 | { 13 | "negetive number: not Automorphic", 14 | -1, 15 | false, 16 | }, 17 | { 18 | "negetive number: not Automorphic", 19 | -146, 20 | false, 21 | }, 22 | { 23 | "0: is Automorphic", 24 | 0, 25 | true, 26 | }, 27 | { 28 | "1: is Automorphic", 29 | 1, 30 | true, 31 | }, 32 | { 33 | "7: not Automorphic", 34 | 7, 35 | false, 36 | }, 37 | { 38 | "83: not Automorphic", 39 | 83, 40 | false, 41 | }, 42 | { 43 | "376: is Automorphic", 44 | 376, 45 | true, 46 | }, 47 | } 48 | 49 | func TestIsAutomorphic(t *testing.T) { 50 | for _, test := range testCases { 51 | t.Run(test.name, func(t *testing.T) { 52 | funcResult := IsAutomorphic(test.input) 53 | if test.expected != funcResult { 54 | t.Errorf("Expected answer '%t' for the number '%d' but answer given was %t", test.expected, test.input, funcResult) 55 | } 56 | }) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /math/krishnamurthy.go: -------------------------------------------------------------------------------- 1 | // filename : krishnamurthy.go 2 | // description: A program which contains the function that returns true if a given number is Krishnamurthy number or not. 3 | // details: A number is a Krishnamurthy number if the sum of all the factorials of the digits is equal to the number. 4 | // Ex: 1! = 1, 145 = 1! + 4! + 5! 5 | // time complexity: O(log n) 6 | // space complexity: O(1) 7 | // author(s): [GooMonk](https://github.com/GooMonk) 8 | // see krishnamurthy_test.go 9 | package math 10 | 11 | import "github.com/TheAlgorithms/Go/constraints" 12 | 13 | // IsKrishnamurthyNumber returns if the provided number n is a Krishnamurthy number or not. 14 | func IsKrishnamurthyNumber[T constraints.Integer](n T) bool { 15 | if n <= 0 { 16 | return false 17 | } 18 | 19 | // Preprocessing: Using a slice to store the digit Factorials 20 | digitFact := make([]T, 10) 21 | digitFact[0] = 1 // 0! = 1 22 | 23 | for i := 1; i < 10; i++ { 24 | digitFact[i] = digitFact[i-1] * T(i) 25 | } 26 | 27 | // Subtract the digit Facotorial from the number 28 | nTemp := n 29 | for n > 0 { 30 | nTemp -= digitFact[n%10] 31 | n /= 10 32 | } 33 | return nTemp == 0 34 | } 35 | -------------------------------------------------------------------------------- /math/lcm/lcm.go: -------------------------------------------------------------------------------- 1 | package lcm 2 | 3 | import ( 4 | "math" 5 | 6 | "github.com/TheAlgorithms/Go/math/gcd" 7 | ) 8 | 9 | // Lcm returns the lcm of two numbers using the fact that lcm(a,b) * gcd(a,b) = | a * b | 10 | func Lcm(a, b int64) int64 { 11 | return int64(math.Abs(float64(a*b)) / float64(gcd.Iterative(a, b))) 12 | } 13 | -------------------------------------------------------------------------------- /math/lcm/lcm_test.go: -------------------------------------------------------------------------------- 1 | package lcm 2 | 3 | import "testing" 4 | 5 | func TestLcm(t *testing.T) { 6 | testCases := []struct { 7 | name string 8 | a int64 9 | b int64 10 | output int64 11 | }{ 12 | { 13 | name: "LCM of 1 & 5", 14 | a: 1, 15 | b: 5, 16 | output: 5, 17 | }, { 18 | name: "LCM of 2 & 5", 19 | a: 2, 20 | b: 5, 21 | output: 10, 22 | }, { 23 | name: "LCM of 5 & 10", 24 | a: 10, 25 | b: 5, 26 | output: 10, 27 | }, { 28 | name: "LCM of 5 & 5", 29 | a: 5, 30 | b: 5, 31 | output: 5, 32 | }, 33 | } 34 | 35 | for _, tc := range testCases { 36 | t.Run(tc.name, func(t *testing.T) { 37 | actual_output := Lcm(tc.a, tc.b) 38 | if actual_output != tc.output { 39 | t.Errorf("Expected LCM of %d and %d is %d, but got %d", tc.a, tc.b, tc.output, 40 | actual_output) 41 | } 42 | }) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /math/lerp.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | // Lerp or Linear interpolation 4 | // This function will return new value in 't' percentage between 'v0' and 'v1' 5 | func Lerp(v0, v1, t float64) float64 { 6 | // see: https://en.wikipedia.org/wiki/Linear_interpolation 7 | return (1-t)*v0 + t*v1 8 | } 9 | -------------------------------------------------------------------------------- /math/lerp_test.go: -------------------------------------------------------------------------------- 1 | package math_test 2 | 3 | import ( 4 | "testing" 5 | 6 | algmath "github.com/TheAlgorithms/Go/math" 7 | ) 8 | 9 | func TestLerp(t *testing.T) { 10 | tests := []struct { 11 | name string 12 | testValues []float64 13 | answer float64 14 | }{ 15 | {"Lerp(1,1,1)", []float64{1, 1, 1}, 1}, 16 | {"Lerp(0,1,1)", []float64{0, 1, 1}, 1}, 17 | {"Lerp(0,1,0.5)", []float64{0, 1, 0.5}, 0.5}, 18 | {"Lerp(0,1,0.1)", []float64{0, 1, 0.1}, 0.1}, 19 | } 20 | for _, test := range tests { 21 | t.Run(test.name, func(t *testing.T) { 22 | got := algmath.Lerp(test.testValues[0], test.testValues[1], test.testValues[2]) 23 | if got != test.answer { 24 | t.Errorf("Lerp(%f,%f,%f) = %v, want %v", got, test.testValues[0], 25 | test.testValues[1], test.testValues[2], test.answer) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /math/liouville.go: -------------------------------------------------------------------------------- 1 | // liouville.go 2 | // description: Returns λ(n) 3 | // details: 4 | // For any positive integer n, define λ(n) as the sum of the primitive nth roots of unity. 5 | // It has values in {−1, 1} depending on the factorization of n into prime factors: 6 | // λ(n) = +1 if n is a positive integer with an even number of prime factors. 7 | // λ(n) = −1 if n is a positive integer with an odd number of prime factors. 8 | // wikipedia: https://en.wikipedia.org/wiki/Liouville_function 9 | // time complexity: O(log n) 10 | // space complexity: O(1) 11 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 12 | // see liouville_test.go 13 | 14 | package math 15 | 16 | import ( 17 | "errors" 18 | 19 | "github.com/TheAlgorithms/Go/math/prime" 20 | ) 21 | 22 | var ErrNonZeroArgsOnly error = errors.New("arguments cannot be zero") 23 | 24 | // Lambda is the liouville function 25 | // This function returns λ(n) for given number 26 | func LiouvilleLambda(n int) (int, error) { 27 | switch { 28 | case n < 0: 29 | return 0, ErrPosArgsOnly 30 | case n == 0: 31 | return 0, ErrNonZeroArgsOnly 32 | case len(prime.Factorize(int64(n)))%2 == 0: 33 | return 1, nil 34 | default: 35 | return -1, nil 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /math/liouville_test.go: -------------------------------------------------------------------------------- 1 | // liouville_test.go 2 | // description: Returns λ(n) 3 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 4 | // see liouville.go 5 | 6 | package math_test 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/TheAlgorithms/Go/math" 12 | ) 13 | 14 | func TestLiouvilleLambda(t *testing.T) { 15 | var tests = []struct { 16 | name string 17 | n int 18 | expectedValue int 19 | expectedError error 20 | }{ 21 | {"n = 10", 10, 1, nil}, 22 | {"n = 11", 11, -1, nil}, 23 | {"n = -1", -1, 0, math.ErrPosArgsOnly}, 24 | {"n = 0", 0, 0, math.ErrNonZeroArgsOnly}, 25 | } 26 | for _, test := range tests { 27 | t.Run(test.name, func(t *testing.T) { 28 | result, err := math.LiouvilleLambda(test.n) 29 | if result != test.expectedValue || test.expectedError != err { 30 | t.Errorf("expected error: %s, got: %s; expected value: %v, got: %v", test.expectedError, err, test.expectedValue, result) 31 | } 32 | }) 33 | } 34 | } 35 | func BenchmarkLiouvilleLambda(b *testing.B) { 36 | for i := 0; i < b.N; i++ { 37 | _, _ = math.LiouvilleLambda(65536) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /math/math_test.go: -------------------------------------------------------------------------------- 1 | // Empty test file to keep track of all the tests for the algorithms. 2 | 3 | package math 4 | -------------------------------------------------------------------------------- /math/matrix/checkequal.go: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | // CheckEqual checks if the current matrix is equal to another matrix (m2). 4 | // Two matrices are considered equal if they have the same dimensions and 5 | // all their elements are equal. 6 | // time complexity: O(n*m) where n and m are the dimensions of the matrix 7 | // space complexity: O(1) 8 | 9 | func (m1 Matrix[T]) CheckEqual(m2 Matrix[T]) bool { 10 | if !m1.MatchDimensions(m2) { 11 | return false 12 | } 13 | 14 | c := make(chan bool) 15 | 16 | for i := range m1.elements { 17 | go func(i int) { 18 | for j := range m1.elements[i] { 19 | if m1.elements[i][j] != m2.elements[i][j] { 20 | c <- false 21 | return 22 | } 23 | } 24 | c <- true 25 | }(i) 26 | } 27 | 28 | for range m1.elements { 29 | if !<-c { 30 | return false 31 | } 32 | } 33 | 34 | return true 35 | } 36 | -------------------------------------------------------------------------------- /math/matrix/isvalid.go: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | import "github.com/TheAlgorithms/Go/constraints" 4 | 5 | // IsValid checks if the input matrix has consistent row lengths. 6 | func IsValid[T constraints.Integer](elements [][]T) bool { 7 | if len(elements) == 0 { 8 | return true 9 | } 10 | columns := len(elements[0]) 11 | for _, row := range elements { 12 | if len(row) != columns { 13 | return false 14 | } 15 | } 16 | return true 17 | } 18 | -------------------------------------------------------------------------------- /math/matrix/matchdimensions.go: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | // MatchDimensions checks if two matrices have the same dimensions. 4 | func (m Matrix[T]) MatchDimensions(m1 Matrix[T]) bool { 5 | if m.rows == m1.rows && m.columns == m1.columns { 6 | return true 7 | } 8 | return false 9 | } 10 | -------------------------------------------------------------------------------- /math/matrix/matchdimensions_test.go: -------------------------------------------------------------------------------- 1 | package matrix_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TheAlgorithms/Go/math/matrix" 7 | ) 8 | 9 | func TestMatrixMatchDimensions(t *testing.T) { 10 | // Create two matrices with the same dimensions 11 | m1 := matrix.New(2, 3, 0) 12 | m2 := matrix.New(2, 3, 0) 13 | 14 | // Test case 1: Same dimensions 15 | if !m1.MatchDimensions(m2) { 16 | t.Errorf("m1.MatchDimensions(m2) returned %t, expected 1 (same dimensions)", m1.MatchDimensions(m2)) 17 | } 18 | 19 | // Create two matrices with different dimensions 20 | m3 := matrix.New(2, 3, 0) 21 | m4 := matrix.New(3, 2, 0) 22 | 23 | // Test case 2: Different dimensions 24 | if m3.MatchDimensions(m4) { 25 | t.Errorf("m3.MatchDimensions(m4) returned : %v, expected: %v", m3.MatchDimensions(m4), false) 26 | } 27 | } 28 | 29 | // BenchmarkMatchDimensions benchmarks the MatchDimensions method. 30 | func BenchmarkMatchDimensions(b *testing.B) { 31 | // Create sample matrices for benchmarking 32 | rows := 100 33 | columns := 100 34 | m1 := matrix.New(rows, columns, 0) // Replace with appropriate values 35 | m2 := matrix.New(rows, columns, 0) // Replace with appropriate values 36 | 37 | for i := 0; i < b.N; i++ { 38 | _ = m1.MatchDimensions(m2) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /math/matrix/string.go: -------------------------------------------------------------------------------- 1 | package matrix 2 | 3 | import "fmt" 4 | 5 | // String implements the fmt.Stringer interface for Matrix. 6 | func (m Matrix[T]) String() string { 7 | var result string 8 | for i := range m.elements { 9 | for j := range m.elements[i] { 10 | result += fmt.Sprintf("%v ", m.elements[i][j]) 11 | } 12 | result += "\n" 13 | } 14 | return result 15 | } 16 | -------------------------------------------------------------------------------- /math/max/bitwisemax.go: -------------------------------------------------------------------------------- 1 | // bitwiseMax.go 2 | // description: Gives max of two integers 3 | // details: 4 | // implementation of finding the maximum of two numbers using only binary operations without using conditions 5 | // author(s) [red_byte](https://github.com/i-redbyte) 6 | // time complexity: O(1) 7 | // space complexity: O(1) 8 | // see bitwiseMax_test.go 9 | 10 | package max 11 | 12 | // Bitwise computes using bitwise operator the maximum of all the integer input and returns it 13 | func Bitwise(a int, b int, base int) int { 14 | z := a - b 15 | i := (z >> base) & 1 16 | return a - (i * z) 17 | } 18 | -------------------------------------------------------------------------------- /math/max/max.go: -------------------------------------------------------------------------------- 1 | package max 2 | 3 | import "github.com/TheAlgorithms/Go/constraints" 4 | 5 | // Int is a function which returns the maximum of all the integers provided as arguments. 6 | func Int[T constraints.Integer](values ...T) T { 7 | max := values[0] 8 | for _, value := range values { 9 | if value > max { 10 | max = value 11 | } 12 | } 13 | return max 14 | } 15 | -------------------------------------------------------------------------------- /math/mean.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "github.com/TheAlgorithms/Go/constraints" 5 | ) 6 | 7 | func Mean[T constraints.Number](values []T) float64 { 8 | 9 | if len(values) == 0 { 10 | return 0 11 | } 12 | 13 | var summation float64 = 0 14 | 15 | for _, singleValue := range values { 16 | summation += float64(singleValue) 17 | } 18 | 19 | return summation / float64(len(values)) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /math/mean_test.go: -------------------------------------------------------------------------------- 1 | package math_test 2 | 3 | import ( 4 | "github.com/TheAlgorithms/Go/math" 5 | "testing" 6 | ) 7 | 8 | func TestMean(t *testing.T) { 9 | testCases := []struct { 10 | name string 11 | testValues []float64 12 | average float64 13 | }{ 14 | { 15 | name: "All 0s", 16 | testValues: []float64{0, 0, 0, 0, 0}, 17 | average: 0, 18 | }, 19 | { 20 | name: "With integer values", 21 | testValues: []float64{1, 2, 3, 4, 5}, 22 | average: 3.0, 23 | }, 24 | { 25 | name: "With negative values", 26 | testValues: []float64{-1, 2, -3, 4, 5}, 27 | average: 1.4, 28 | }, 29 | { 30 | name: "With floating values", 31 | testValues: []float64{1.1, 2.2, 3.3, 4.4, 5.5}, 32 | average: 3.3, 33 | }, 34 | { 35 | name: "With no values", 36 | testValues: []float64{}, 37 | average: 0, 38 | }, 39 | } 40 | 41 | for _, test := range testCases { 42 | t.Run(test.name, func(t *testing.T) { 43 | returnedAverage := math.Mean(test.testValues) 44 | if returnedAverage != test.average { 45 | t.Errorf("\nFailed test: %s\ntestValues: %v\naverage: %v\nbut received: %v\n", 46 | test.name, test.testValues, test.average, returnedAverage) 47 | } 48 | 49 | }) 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /math/median.go: -------------------------------------------------------------------------------- 1 | // author(s) [jo3zeph](https://github.com/jo3zeph) 2 | // description: Find the median from a set of values 3 | // time complexity: O(n log n) 4 | // space complexity: O(1) 5 | // see median_test.go 6 | 7 | package math 8 | 9 | import ( 10 | "github.com/TheAlgorithms/Go/constraints" 11 | "github.com/TheAlgorithms/Go/sort" 12 | ) 13 | 14 | func Median[T constraints.Number](values []T) float64 { 15 | 16 | sort.Bubble(values) 17 | 18 | l := len(values) 19 | 20 | switch { 21 | case l == 0: 22 | return 0 23 | 24 | case l%2 == 0: 25 | return float64((values[l/2-1] + values[l/2]) / 2) 26 | 27 | default: 28 | return float64(values[l/2]) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /math/min/bitwisemin.go: -------------------------------------------------------------------------------- 1 | // bitwisemin.go 2 | // description: Gives min of two integers 3 | // details: 4 | // implementation of finding the minimum of two numbers using only binary operations without using conditions 5 | // author(s) [red_byte](https://github.com/i-redbyte) 6 | // see bitwisemin_test.go 7 | 8 | package min 9 | 10 | // Bitwise This function returns the minimum integer using bit operations 11 | func Bitwise(base int, value int, values ...int) int { 12 | min := value 13 | for _, val := range values { 14 | min = min&((min-val)>>base) | val&(^(min-val)>>base) 15 | } 16 | return min 17 | } 18 | -------------------------------------------------------------------------------- /math/min/min.go: -------------------------------------------------------------------------------- 1 | package min 2 | 3 | import "github.com/TheAlgorithms/Go/constraints" 4 | 5 | // Int is a function which returns the minimum of all the integers provided as arguments. 6 | func Int[T constraints.Integer](values ...T) T { 7 | min := values[0] 8 | for _, value := range values { 9 | if value < min { 10 | min = value 11 | } 12 | } 13 | return min 14 | } 15 | -------------------------------------------------------------------------------- /math/mobius.go: -------------------------------------------------------------------------------- 1 | // mobius.go 2 | // description: Returns μ(n) 3 | // details: 4 | // For any positive integer n, define μ(n) as the sum of the primitive nth roots of unity. 5 | // It has values in {−1, 0, 1} depending on the factorization of n into prime factors: 6 | // μ(n) = +1 if n is a square-free positive integer with an even number of prime factors. 7 | // μ(n) = −1 if n is a square-free positive integer with an odd number of prime factors. 8 | // μ(n) = 0 if n has a squared prime factor. 9 | // wikipedia: https://en.wikipedia.org/wiki/M%C3%B6bius_function 10 | // time complexity: O(n) 11 | // space complexity: O(1) 12 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 13 | // see mobius_test.go 14 | 15 | package math 16 | 17 | import ( 18 | "github.com/TheAlgorithms/Go/math/prime" 19 | ) 20 | 21 | // Mu is the Mobius function 22 | // This function returns μ(n) for given number 23 | func Mu(n int) int { 24 | if n <= 1 { 25 | return 1 26 | } 27 | var primeFactorCount int 28 | for i := 1; i <= n; i++ { 29 | if n%i == 0 && prime.OptimizedTrialDivision(int64(i)) { 30 | if n%(i*i) == 0 { 31 | return 0 32 | } 33 | primeFactorCount += 1 34 | } 35 | } 36 | if primeFactorCount%2 == 0 { 37 | return 1 38 | } 39 | return -1 40 | } 41 | -------------------------------------------------------------------------------- /math/mobius_test.go: -------------------------------------------------------------------------------- 1 | // mobius_test.go 2 | // description: Returns μ(n) 3 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 4 | // see mobius.go 5 | 6 | package math_test 7 | 8 | import ( 9 | "testing" 10 | 11 | algmath "github.com/TheAlgorithms/Go/math" 12 | ) 13 | 14 | func TestMu(t *testing.T) { 15 | var tests = []struct { 16 | n int 17 | expected int 18 | }{ 19 | {-1, 1}, 20 | {0, 1}, 21 | {2, -1}, 22 | {3, -1}, 23 | {95, 1}, 24 | {97, -1}, 25 | {98, 0}, 26 | {99, 0}, 27 | {100, 0}, 28 | } 29 | for _, test := range tests { 30 | result := algmath.Mu(test.n) 31 | t.Log(test.n, " ", result) 32 | if result != test.expected { 33 | t.Errorf("Wrong result! Expected:%v, returned:%v ", test.expected, result) 34 | } 35 | } 36 | } 37 | func BenchmarkMu(b *testing.B) { 38 | for i := 0; i < b.N; i++ { 39 | algmath.Mu(65536) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /math/mode.go: -------------------------------------------------------------------------------- 1 | // mode.go 2 | // author(s): [CalvinNJK] (https://github.com/CalvinNJK) 3 | // time complexity: O(n) 4 | // space complexity: O(n) 5 | // description: Finding Mode Value In an Array 6 | // see mode.go 7 | 8 | package math 9 | 10 | import ( 11 | "errors" 12 | 13 | "github.com/TheAlgorithms/Go/constraints" 14 | ) 15 | 16 | // ErrEmptySlice is the error returned by functions in math package when 17 | // an empty slice is provided to it as argument when the function expects 18 | // a non-empty slice. 19 | var ErrEmptySlice = errors.New("empty slice provided") 20 | 21 | func Mode[T constraints.Number](numbers []T) (T, error) { 22 | 23 | countMap := make(map[T]int) 24 | 25 | n := len(numbers) 26 | 27 | if n == 0 { 28 | return 0, ErrEmptySlice 29 | } 30 | 31 | for _, number := range numbers { 32 | countMap[number]++ 33 | } 34 | 35 | var mode T 36 | count := 0 37 | 38 | for k, v := range countMap { 39 | if v > count { 40 | count = v 41 | mode = k 42 | } 43 | } 44 | 45 | return mode, nil 46 | 47 | } 48 | -------------------------------------------------------------------------------- /math/modular/inverse.go: -------------------------------------------------------------------------------- 1 | // inverse.go 2 | // description: Implementation of Modular Inverse Algorithm 3 | // details: 4 | // A simple implementation of Modular Inverse - [Modular Inverse wiki](https://en.wikipedia.org/wiki/Modular_multiplicative_inverse) 5 | // time complexity: O(log(min(a, b))) where a and b are the two numbers 6 | // space complexity: O(1) 7 | // author(s) [Taj](https://github.com/tjgurwara99) 8 | // see inverse_test.go 9 | 10 | package modular 11 | 12 | import ( 13 | "errors" 14 | 15 | "github.com/TheAlgorithms/Go/math/gcd" 16 | ) 17 | 18 | var ErrorInverse = errors.New("no Modular Inverse exists") 19 | 20 | // Inverse Modular function 21 | func Inverse(a, m int64) (int64, error) { 22 | gcd, x, _ := gcd.Extended(a, m) 23 | if gcd != 1 || m == 0 { 24 | return 0, ErrorInverse 25 | } 26 | 27 | return ((m + (x % m)) % m), nil // this is necessary because of Go's use of architecture specific instruction for the % operator. 28 | } 29 | -------------------------------------------------------------------------------- /math/modular/inverse_test.go: -------------------------------------------------------------------------------- 1 | // inverse_test.go 2 | // description: Test for Modular Inverse 3 | // author(s) [Taj](https://github.com/tjgurwara99) 4 | // see inverse.go 5 | 6 | package modular 7 | 8 | import "testing" 9 | import "fmt" 10 | 11 | func TestInverse(t *testing.T) { 12 | testCases := []struct { 13 | a int64 14 | m int64 15 | expectedValue int64 16 | expectedError error 17 | }{ 18 | {3, 11, 4, nil}, 19 | {10, 17, 12, nil}, 20 | {2, 6, 0, ErrorInverse}, 21 | {1, 0, 0, ErrorInverse}, 22 | } 23 | for _, tc := range testCases { 24 | testName := fmt.Sprintf("Testing a = %d and m = %d: ", tc.a, tc.m) 25 | t.Run(testName, func(t *testing.T) { 26 | inv, err := Inverse(tc.a, tc.m) 27 | if err != tc.expectedError { 28 | if tc.expectedError == nil { 29 | t.Fatalf("Error was raised when it shouldn't: %v", err) 30 | } else { 31 | t.Fatalf("Error was not raised when it should") 32 | } 33 | } 34 | if inv != tc.expectedValue { 35 | t.Fatalf("expected: %d, got: %d", tc.expectedValue, inv) 36 | } 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /math/moserdebruijnsequence/sequence.go: -------------------------------------------------------------------------------- 1 | // The Moser-de Bruijn sequence is the sequence obtained by 2 | // adding up the distinct powers of the number 4 (For example 1, 4, 16, 64, etc). 3 | // time complexity: O(n) 4 | // space complexity: O(n) 5 | // You can get more details on https://en.wikipedia.org/wiki/Moser%E2%80%93de_Bruijn_sequence. 6 | 7 | package moserdebruijnsequence 8 | 9 | func MoserDeBruijnSequence(number int) []int { 10 | sequence := []int{} 11 | 12 | for i := 0; i < number; i++ { 13 | res := generateNthTerm(i) 14 | sequence = append(sequence, res) 15 | } 16 | 17 | return sequence 18 | } 19 | 20 | func generateNthTerm(num int) int { 21 | if num == 0 || num == 1 { 22 | return num 23 | } 24 | 25 | //number is even 26 | if num%2 == 0 { 27 | return 4 * generateNthTerm(num/2) 28 | } 29 | 30 | //number is odd 31 | return 4*generateNthTerm(num/2) + 1 32 | } 33 | -------------------------------------------------------------------------------- /math/moserdebruijnsequence/sequence_test.go: -------------------------------------------------------------------------------- 1 | package moserdebruijnsequence 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | var testCases = []struct { 9 | name string 10 | inputNum int 11 | expected []int 12 | }{ 13 | {"first 15 terms", 15, []int{0, 1, 4, 5, 16, 17, 20, 21, 64, 65, 68, 69, 80, 81, 84}}, 14 | } 15 | 16 | func TestMoserDeBruijnSequence(t *testing.T) { 17 | 18 | for _, test := range testCases { 19 | t.Run(test.name, func(t *testing.T) { 20 | if output := MoserDeBruijnSequence(test.inputNum); !reflect.DeepEqual(output, test.expected) { 21 | t.Errorf("For input: %d, expected: %v, but got: %v", test.inputNum, test.expected, output) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /math/pascal/pascaltriangle.go: -------------------------------------------------------------------------------- 1 | // pascaltriangle.go 2 | // description: Pascal's triangle 3 | // details: 4 | // Pascal's triangle is a triangular array of the binomial coefficients that arises in probability theory, combinatorics, and algebra. - [Pascal's triangle](https://en.wikipedia.org/wiki/Pascal%27s_triangle) 5 | // example: 6 | //1 7 | //1 1 8 | //1 2 1 9 | //1 3 3 1 10 | //1 4 6 4 1 11 | //1 5 10 10 5 1 12 | //1 6 15 20 15 6 1 13 | //1 7 21 35 35 21 7 1 14 | //1 8 28 56 70 56 28 8 1 15 | //1 9 36 84 126 126 84 36 9 1 16 | //1 10 45 120 210 252 210 120 45 10 1 17 | //... 18 | // author(s) [red_byte](https://github.com/i-redbyte) 19 | // time complexity: O(n^2) 20 | // space complexity: O(n^2) 21 | // see pascaltriangle_test.go 22 | 23 | package pascal 24 | 25 | // GenerateTriangle This function generates a Pascal's triangle of n lines 26 | func GenerateTriangle(n int) [][]int { 27 | var triangle = make([][]int, n) 28 | for i := 0; i < n; i++ { 29 | triangle[i] = make([]int, i+1) 30 | triangle[i][0], triangle[i][i] = 1, 1 31 | for j := 1; j < i; j++ { 32 | triangle[i][j] = triangle[i-1][j] + triangle[i-1][j-1] 33 | } 34 | } 35 | return triangle 36 | } 37 | -------------------------------------------------------------------------------- /math/pascal/pascaltriangle_test.go: -------------------------------------------------------------------------------- 1 | // pascaltriangle_test.go 2 | // description: Test for Pascal's triangle 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see pascaltriangle.go 5 | 6 | package pascal 7 | 8 | import ( 9 | "reflect" 10 | "testing" 11 | ) 12 | 13 | func TestGenerateTriangle(t *testing.T) { 14 | tests := []struct { 15 | name string 16 | n int 17 | want [][]int 18 | }{ 19 | {name: "Pascal's three-line triangle", n: 3, want: [][]int{{1}, {1, 1}, {1, 2, 1}}}, 20 | {name: "Pascal's 0-line triangle", n: 0, want: [][]int{}}, 21 | {name: "Pascal's one-line triangle", n: 1, want: [][]int{{1}}}, 22 | {name: "Pascal's 7-line triangle", n: 7, want: [][]int{{1}, {1, 1}, {1, 2, 1}, {1, 3, 3, 1}, {1, 4, 6, 4, 1}, {1, 5, 10, 10, 5, 1}, {1, 6, 15, 20, 15, 6, 1}}}, 23 | } 24 | for _, test := range tests { 25 | t.Run(test.name, func(t *testing.T) { 26 | if got := GenerateTriangle(test.n); !reflect.DeepEqual(got, test.want) { 27 | t.Errorf("GenerateTriangle() = %v, want %v", got, test.want) 28 | } 29 | }) 30 | } 31 | } 32 | 33 | func BenchmarkGenerateTriangle(b *testing.B) { 34 | for i := 0; i < b.N; i++ { 35 | GenerateTriangle(10) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /math/permutation/next_permutation_test.go: -------------------------------------------------------------------------------- 1 | package permutation 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestNextPermutation(t *testing.T) { 9 | var nextPermutationTestData = []struct { 10 | description string 11 | numbers []int 12 | next []int 13 | }{ 14 | { 15 | description: "Basic case", 16 | numbers: []int{1, 2, 3}, 17 | next: []int{1, 3, 2}, 18 | }, 19 | { 20 | description: "Should reverse the whole slice", 21 | numbers: []int{3, 2, 1}, 22 | next: []int{1, 2, 3}, 23 | }, 24 | { 25 | description: "A more complex test", 26 | numbers: []int{2, 4, 1, 7, 5, 0}, 27 | next: []int{2, 4, 5, 0, 1, 7}, 28 | }, 29 | } 30 | for _, test := range nextPermutationTestData { 31 | t.Run(test.description, func(t *testing.T) { 32 | NextPermutation(test.numbers) 33 | 34 | if !reflect.DeepEqual(test.numbers, test.next) { 35 | t.Logf("FAIL: %s", test.description) 36 | t.Fatalf("Expected result:%v\nFound: %v", test.next, test.numbers) 37 | } 38 | }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /math/power/fastexponent.go: -------------------------------------------------------------------------------- 1 | package power 2 | 3 | // IterativePower is iterative O(logn) function for pow(x, y) 4 | func IterativePower(n uint, power uint) uint { 5 | var res uint = 1 6 | for power > 0 { 7 | if (power & 1) != 0 { 8 | res = res * n 9 | } 10 | 11 | power = power >> 1 12 | n *= n 13 | } 14 | return res 15 | } 16 | 17 | // RecursivePower is recursive O(logn) function for pow(x, y) 18 | func RecursivePower(n uint, power uint) uint { 19 | if power == 0 { 20 | return 1 21 | } 22 | var temp = RecursivePower(n, power/2) 23 | if power%2 == 0 { 24 | return temp * temp 25 | } 26 | return n * temp * temp 27 | } 28 | 29 | // RecursivePower1 is recursive O(n) function for pow(x, y) 30 | func RecursivePower1(n uint, power uint) uint { 31 | if power == 0 { 32 | return 1 33 | } else if power%2 == 0 { 34 | return RecursivePower1(n, power/2) * RecursivePower1(n, power/2) 35 | } else { 36 | return n * RecursivePower1(n, power/2) * RecursivePower1(n, power/2) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /math/power/powvialogarithm.go: -------------------------------------------------------------------------------- 1 | // powvialogarithm.go 2 | // description: Powers in terms of logarithms 3 | // details: 4 | // implementation of exponentiation using exponent and logarithm, without using loops - [Powers via logarithms wiki](https://en.wikipedia.org/wiki/Exponentiation#Powers_via_logarithms) 5 | // time complexity: O(1) 6 | // space complexity: O(1) 7 | // author(s) [red_byte](https://github.com/i-redbyte) 8 | // see powvialogarithm_test.go 9 | 10 | package power 11 | 12 | import ( 13 | "math" 14 | ) 15 | 16 | func UsingLog(a float64, b float64) float64 { 17 | var p float64 18 | p = 1 19 | if a < 0 && int(b)&1 != 0 { 20 | p = -1 21 | } 22 | log := math.Log(math.Abs(a)) 23 | exp := math.Exp(b * log) 24 | result := exp * p 25 | return math.Round(result) 26 | } 27 | -------------------------------------------------------------------------------- /math/power/powvialogarithm_test.go: -------------------------------------------------------------------------------- 1 | // powvialogarithm_test.go 2 | // description: Test for UsingLog 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see powvialogarithm.go 5 | 6 | package power 7 | 8 | import "testing" 9 | 10 | func TestUsingLog(t *testing.T) { 11 | var tests = []struct { 12 | name string 13 | base float64 14 | power float64 15 | expected float64 16 | }{ 17 | {"0^0", 99, 1, 99}, 18 | {"-3^9", -3, 9, -19683}, 19 | {"0^2", 0, 2, 0}, 20 | {"2^0", 2, 0, 1}, 21 | {"2^3", 2, 3, 8}, 22 | {"8^3", 8, 3, 512}, 23 | {"11^11", 11, 11, 285311670611}, 24 | {"5^5", 5, 5, 3125}, 25 | {"-7^2", -7, 2, 49}, 26 | {"-6^3", -6, 3, -216}, 27 | } 28 | 29 | for _, tc := range tests { 30 | t.Run(tc.name, func(t *testing.T) { 31 | result := UsingLog(tc.base, tc.power) 32 | t.Log(result) 33 | if result != tc.expected { 34 | t.Errorf("Expected %.2f to the power of %.2f to be: %.2f, but got: %.2f", tc.base, tc.power, tc.expected, result) 35 | } 36 | }) 37 | } 38 | } 39 | 40 | func BenchmarkUsingLog(b *testing.B) { 41 | for i := 0; i < b.N; i++ { 42 | UsingLog(10, 5) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /math/prime/primefactorization.go: -------------------------------------------------------------------------------- 1 | // primefactorization.go 2 | // description: Prime factorization of a number 3 | // time complexity: O(sqrt(n)) 4 | // space complexity: O(sqrt(n)) 5 | 6 | package prime 7 | 8 | // Factorize is a function that computes the exponents 9 | // of each prime in the prime factorization of n 10 | func Factorize(n int64) map[int64]int64 { 11 | result := make(map[int64]int64) 12 | 13 | for i := int64(2); i*i <= n; i += 1 { 14 | for { 15 | if n%i != 0 { 16 | break 17 | } 18 | result[i] += 1 19 | n /= i 20 | } 21 | 22 | } 23 | if n > 1 { 24 | result[n] += 1 25 | } 26 | return result 27 | } 28 | -------------------------------------------------------------------------------- /math/prime/primefactorization_test.go: -------------------------------------------------------------------------------- 1 | package prime 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestFactorize(t *testing.T) { 9 | var tests = []struct { 10 | n int64 11 | expected map[int64]int64 12 | }{ 13 | {4, map[int64]int64{2: 2}}, 14 | {5, map[int64]int64{5: 1}}, 15 | {7, map[int64]int64{7: 1}}, 16 | {10, map[int64]int64{2: 1, 5: 1}}, 17 | {999, map[int64]int64{3: 3, 37: 1}}, 18 | {999999999999878, map[int64]int64{2: 1, 19: 1, 26315789473681: 1}}, 19 | } 20 | for _, test := range tests { 21 | result := Factorize(test.n) 22 | t.Log(test.n, " ", result) 23 | if !reflect.DeepEqual(result, test.expected) { 24 | t.Errorf("Wrong result! Expected:%v, returned:%v ", test.expected, result) 25 | } 26 | } 27 | } 28 | 29 | func BenchmarkFactorize(b *testing.B) { 30 | for i := 0; i < b.N; i++ { 31 | Factorize(1000000007) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /math/prime/sieve.go: -------------------------------------------------------------------------------- 1 | // sieve.go 2 | // description: Algorithms for generating prime numbers efficiently 3 | // author(s) [Taj](https://github.com/tjgurwara99) 4 | // see sieve_test.go 5 | 6 | package prime 7 | 8 | // Generate generates the sequence of integers starting at 2 and sends it to the channel `ch` 9 | func GenerateChannel(ch chan<- int) { 10 | for i := 2; ; i++ { 11 | ch <- i 12 | } 13 | } 14 | 15 | // Sieve Sieving the numbers that are not prime from the channel - basically removing them from the channels 16 | func Sieve(in <-chan int, out chan<- int, prime int) { 17 | for { 18 | i := <-in 19 | if i%prime != 0 { 20 | out <- i 21 | } 22 | } 23 | } 24 | 25 | // Generate returns a int slice of prime numbers up to the limit 26 | func Generate(limit int) []int { 27 | var primes []int 28 | 29 | ch := make(chan int) 30 | go GenerateChannel(ch) 31 | 32 | for i := 0; i < limit; i++ { 33 | primes = append(primes, <-ch) 34 | ch1 := make(chan int) 35 | go Sieve(ch, ch1, primes[i]) 36 | ch = ch1 37 | } 38 | 39 | return primes 40 | } 41 | -------------------------------------------------------------------------------- /math/prime/sieve2.go: -------------------------------------------------------------------------------- 1 | /* sieve2.go - Sieve of Eratosthenes 2 | * Algorithm to generate prime numbers up to a limit 3 | * time complexity: O(n log log n) 4 | * space complexity: O(n) 5 | * Author: ddaniel27 6 | */ 7 | package prime 8 | 9 | func SieveEratosthenes(limit int) []int { 10 | primes := make([]int, 0) 11 | sieve := make([]int, limit+1) // make a slice of size limit+1 12 | 13 | for i := 2; i <= limit; i++ { 14 | if sieve[i] == 0 { // if the number is not marked as composite 15 | primes = append(primes, i) // add it to the list of primes 16 | for j := i * i; j <= limit; j += i { // mark all multiples of i as composite 17 | sieve[j] = 1 18 | } 19 | } 20 | } 21 | 22 | return primes 23 | } 24 | -------------------------------------------------------------------------------- /math/prime/sieve2_test.go: -------------------------------------------------------------------------------- 1 | package prime_test 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | "github.com/TheAlgorithms/Go/math/prime" 8 | ) 9 | 10 | func TestSieveEratosthenes(t *testing.T) { 11 | tests := []struct { 12 | name string 13 | limit int 14 | want []int 15 | }{ 16 | { 17 | name: "First 10 primes test", 18 | limit: 30, 19 | want: []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29}, 20 | }, 21 | { 22 | name: "First 20 primes test", 23 | limit: 71, 24 | want: []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71}, 25 | }, 26 | } 27 | 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | got := prime.SieveEratosthenes(tt.limit) 31 | 32 | if !reflect.DeepEqual(got, tt.want) { 33 | t.Errorf("SieveEratosthenes() = %v, want %v", got, tt.want) 34 | } 35 | }) 36 | } 37 | } 38 | 39 | func BenchmarkSieveEratosthenes(b *testing.B) { 40 | for i := 0; i < b.N; i++ { 41 | _ = prime.SieveEratosthenes(10) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /math/prime/twin.go: -------------------------------------------------------------------------------- 1 | // twin.go 2 | // description: Returns Twin Prime of n 3 | // details: 4 | // For any integer n, twin prime is (n + 2) 5 | // if and only if both n and (n + 2) both are prime 6 | // wikipedia: https://en.wikipedia.org/wiki/Twin_prime 7 | // time complexity: O(log n) 8 | // space complexity: O(1) 9 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 10 | // see twin_test.go 11 | 12 | package prime 13 | 14 | // This function returns twin prime for given number 15 | // returns (n + 2) if both n and (n + 2) are prime 16 | // -1 otherwise 17 | func Twin(n int) (int, bool) { 18 | if OptimizedTrialDivision(int64(n)) && OptimizedTrialDivision(int64(n+2)) { 19 | return n + 2, true 20 | } 21 | return -1, false 22 | } 23 | -------------------------------------------------------------------------------- /math/prime/twin_test.go: -------------------------------------------------------------------------------- 1 | // twin_test.go 2 | // description: Returns Twin Prime of n 3 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 4 | // see twin.go 5 | 6 | package prime_test 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/TheAlgorithms/Go/math/prime" 12 | ) 13 | 14 | func TestTwin(t *testing.T) { 15 | var tests = []struct { 16 | name string 17 | n int 18 | expectedValue int 19 | hasTwin bool 20 | }{ 21 | {"n = 3, should return 5", 3, 5, true}, 22 | {"n = 4, should return -1", 4, -1, false}, 23 | {"n = 5, should return 7", 5, 7, true}, 24 | {"n = 17, should return 19", 17, 19, true}, 25 | } 26 | for _, test := range tests { 27 | t.Run(test.name, func(t *testing.T) { 28 | result, hasTwin := prime.Twin(test.n) 29 | if result != test.expectedValue || hasTwin != test.hasTwin { 30 | t.Errorf("expected value: %v and %v, got: %v and %v", test.expectedValue, test.hasTwin, result, hasTwin) 31 | } 32 | }) 33 | } 34 | } 35 | func BenchmarkTwin(b *testing.B) { 36 | for i := 0; i < b.N; i++ { 37 | _, _ = prime.Twin(65536) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /math/pronicnumber.go: -------------------------------------------------------------------------------- 1 | // pronicnumber.go 2 | // description: Returns true if the number is pronic and false otherwise 3 | // details: 4 | // Pronic number: For any integer n, if there exists integer m 5 | // such that n = m * (m + 1) then n is called a pronic number. 6 | // wikipedia: https://en.wikipedia.org/wiki/Pronic_number 7 | // time complexity: O(1) 8 | // space complexity: O(1) 9 | // author: Akshay Dubey (https://github.com/itsAkshayDubey) 10 | // see pronicnumber_test.go 11 | 12 | package math 13 | 14 | import "math" 15 | 16 | // PronicNumber returns true if argument passed to the function is pronic and false otherwise. 17 | func PronicNumber(n int) bool { 18 | if n < 0 || n%2 == 1 { 19 | return false 20 | } 21 | x := int(math.Sqrt(float64(n))) 22 | return n == x*(x+1) 23 | } 24 | -------------------------------------------------------------------------------- /math/pythagoras/pythagoras.go: -------------------------------------------------------------------------------- 1 | package pythagoras 2 | 3 | import ( 4 | "math" 5 | ) 6 | 7 | // Vector defines a tuple with 3 values in 3d-space 8 | type Vector struct { 9 | x float64 10 | y float64 11 | z float64 12 | } 13 | 14 | // Distance calculates the distance between to vectors with the Pythagoras theorem 15 | func Distance(a, b Vector) float64 { 16 | res := math.Pow(b.x-a.x, 2.0) + math.Pow(b.y-a.y, 2.0) + math.Pow(b.z-a.z, 2.0) 17 | return math.Sqrt(res) 18 | } 19 | -------------------------------------------------------------------------------- /math/sin.go: -------------------------------------------------------------------------------- 1 | // author(s) [red_byte](https://github.com/i-redbyte) 2 | // see sin_test.go 3 | 4 | package math 5 | 6 | import "math" 7 | 8 | // Sin returns the sine of the radian argument x. [See more](https://en.wikipedia.org/wiki/Sine_and_cosine) 9 | func Sin(x float64) float64 { 10 | return Cos((math.Pi / 2) - x) 11 | } 12 | -------------------------------------------------------------------------------- /math/sin_test.go: -------------------------------------------------------------------------------- 1 | package math_test 2 | 3 | import ( 4 | algmath "github.com/TheAlgorithms/Go/math" 5 | stdmath "math" 6 | "testing" 7 | ) 8 | 9 | func TestSin(t *testing.T) { 10 | tests := []struct { 11 | name string 12 | n float64 13 | want float64 14 | }{ 15 | {"sin(0)", 0, 0}, 16 | {"sin(3π/2)", (3 * stdmath.Pi) / 2, -1}, 17 | {"sin(π/2)", stdmath.Pi / 2, 1}, 18 | {"sin(π/6)", stdmath.Pi / 6, 0.5}, 19 | {"sin(90)", 90, 0.893996663600558}, 20 | } 21 | for _, test := range tests { 22 | t.Run(test.name, func(t *testing.T) { 23 | got := algmath.Sin(test.n) 24 | if stdmath.Abs(got-test.want) >= epsilon { 25 | t.Errorf("Sin() = %v, want %v", got, test.want) 26 | t.Errorf("MATH Sin() = %v", stdmath.Sin(test.n)) 27 | } 28 | }) 29 | } 30 | } 31 | 32 | func BenchmarkSin(b *testing.B) { 33 | for i := 0; i < b.N; i++ { 34 | algmath.Sin(180) 35 | } 36 | } 37 | 38 | // BenchmarkMathSin is slower because the standard library `math.Sin` calculates a more accurate value. 39 | func BenchmarkMathSin(b *testing.B) { 40 | for i := 0; i < b.N; i++ { 41 | stdmath.Sin(180) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /other/doc.go: -------------------------------------------------------------------------------- 1 | // Package other is dedicated to algorithms that 2 | // do not quite fit into any of the other subpackages in this repository. 3 | package other 4 | -------------------------------------------------------------------------------- /other/maxsubarraysum/maxsubarraysum.go: -------------------------------------------------------------------------------- 1 | /* O(n) solution, for calculating 2 | maximum contiguous sum in the given array. */ 3 | 4 | // Package maxsubarraysum is a package containing a solution to a common 5 | // problem of finding max contiguous sum within a array of ints. 6 | package maxsubarraysum 7 | 8 | import ( 9 | "github.com/TheAlgorithms/Go/math/max" 10 | ) 11 | 12 | // MaxSubarraySum returns the maximum subarray sum 13 | func MaxSubarraySum(array []int) int { 14 | var currentMax int 15 | var maxTillNow int 16 | if len(array) != 0 { 17 | currentMax = array[0] 18 | maxTillNow = array[0] 19 | } 20 | for _, v := range array { 21 | currentMax = max.Int(v, currentMax+v) 22 | maxTillNow = max.Int(maxTillNow, currentMax) 23 | } 24 | return maxTillNow 25 | } 26 | -------------------------------------------------------------------------------- /other/maxsubarraysum/maxsubarraysum_test.go: -------------------------------------------------------------------------------- 1 | package maxsubarraysum 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestMaxSubarraySum(t *testing.T) { 8 | testCases := []struct { 9 | name string 10 | slice []int 11 | expected int 12 | }{ 13 | { 14 | name: "Empty slice", 15 | slice: []int{}, 16 | expected: 0, 17 | }, 18 | { 19 | name: "Max is 0", 20 | slice: []int{0, -1, -2, -4, -5}, 21 | expected: 0, 22 | }, 23 | { 24 | name: "Max is -1", 25 | slice: []int{-1, -3, -2, -5, -7}, 26 | expected: -1, 27 | }, 28 | { 29 | name: "Max is 7", 30 | slice: []int{-2, -5, 6, 0, -2, 0, -3, 1, 0, 5, -6}, 31 | expected: 7, 32 | }, 33 | } 34 | for _, test := range testCases { 35 | t.Run(test.name, func(t *testing.T) { 36 | if result := MaxSubarraySum(test.slice); result != test.expected { 37 | t.Fatalf("%s\n\tslice: %v, expected: %v, returned: %v", test.name, test.slice, test.expected, result) 38 | } 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /other/other_test.go: -------------------------------------------------------------------------------- 1 | // Empty test file to keep track of all the tests for the algorithms. 2 | 3 | package other 4 | -------------------------------------------------------------------------------- /project_euler/problem_1/problem1.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 1 - Multiples of 3 and 5 3 | * 4 | * @see {@link https://projecteuler.net/problem=1} 5 | * 6 | * If we list all the natural numbers below 10 that are multiples of 3 or 5, 7 | * we get 3, 5, 6 and 9. The sum of these multiples is 23. 8 | * Find the sum of all the multiples of 3 or 5 below 1000. 9 | * 10 | * @author ddaniel27 11 | */ 12 | package problem1 13 | 14 | func Problem1(n uint) uint { 15 | sum := uint(0) 16 | 17 | for i := uint(1); i < n; i++ { 18 | if i%3 == 0 || i%5 == 0 { 19 | sum += i 20 | } 21 | } 22 | 23 | return sum 24 | } 25 | -------------------------------------------------------------------------------- /project_euler/problem_1/problem1_test.go: -------------------------------------------------------------------------------- 1 | package problem1 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem1_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | threshold uint 10 | want uint 11 | }{ 12 | { 13 | name: "Testcase 1 - threshold 10", 14 | threshold: 10, 15 | want: 23, 16 | }, 17 | { 18 | name: "Testcase 2 - threshold 100", 19 | threshold: 100, 20 | want: 2318, 21 | }, 22 | { 23 | name: "Testcase 3 - threshold 1000", 24 | threshold: 1000, 25 | want: 233168, 26 | }, 27 | } 28 | 29 | for _, tt := range tests { 30 | t.Run(tt.name, func(t *testing.T) { 31 | n := Problem1(tt.threshold) 32 | 33 | if n != tt.want { 34 | t.Errorf("Problem1() = %v, want %v", n, tt.want) 35 | } 36 | }) 37 | } 38 | } 39 | 40 | // Benchmarks 41 | func BenchmarkProblem1(b *testing.B) { 42 | for i := 0; i < b.N; i++ { 43 | _ = Problem1(1000) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /project_euler/problem_10/problem10.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 10 - Summation of primes 3 | * @see {@link https://projecteuler.net/problem=10} 4 | * 5 | * The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. 6 | * Find the sum of all the primes below two million. 7 | * 8 | * @author ddaniel27 9 | */ 10 | package problem10 11 | 12 | import "github.com/TheAlgorithms/Go/math/prime" 13 | 14 | func Problem10(n int) uint { 15 | sum := uint(0) 16 | sieve := prime.SieveEratosthenes(n) 17 | 18 | for _, v := range sieve { 19 | sum += uint(v) 20 | } 21 | 22 | return sum 23 | } 24 | -------------------------------------------------------------------------------- /project_euler/problem_10/problem10_test.go: -------------------------------------------------------------------------------- 1 | package problem10 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem10_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input int 10 | want uint 11 | }{ 12 | { 13 | name: "Testcase 1 - input 10", 14 | input: 10, 15 | want: 17, 16 | }, 17 | { 18 | name: "Testcase 2 - input 2000000", 19 | input: 2000000, 20 | want: 142913828922, 21 | }, 22 | } 23 | 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | n := Problem10(tt.input) 27 | 28 | if n != tt.want { 29 | t.Errorf("Problem10() = %v, want %v", n, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | 35 | // Benchmarks 36 | func BenchmarkProblem10(b *testing.B) { 37 | for i := 0; i < b.N; i++ { 38 | _ = Problem10(2000000) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /project_euler/problem_11/problem11_test.go: -------------------------------------------------------------------------------- 1 | package problem11 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem11_Func(t *testing.T) { 7 | testCases := []struct { 8 | name string 9 | expected uint 10 | }{ 11 | {"Test Case 1", 70600674}, 12 | } 13 | 14 | for _, tc := range testCases { 15 | t.Run(tc.name, func(t *testing.T) { 16 | actual := Problem11() 17 | if actual != tc.expected { 18 | t.Errorf("Expected: %v, but got %v", tc.expected, actual) 19 | } 20 | }) 21 | } 22 | } 23 | 24 | // Benchmark 25 | func BenchmarkProblem11_Func(b *testing.B) { 26 | for i := 0; i < b.N; i++ { 27 | Problem11() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /project_euler/problem_12/problem12.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 12 - Highly divisible triangular number 3 | * @see {@link https://projecteuler.net/problem=12} 4 | * 5 | * The sequence of triangle numbers is generated by adding the natural numbers. 6 | * So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. 7 | * The first ten terms would be: 8 | * 9 | * 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... 10 | * 11 | * Let us list the factors of the first seven triangle numbers: 12 | * 13 | * 1: 1 14 | * 3: 1,3 15 | * 6: 1,2,3,6 16 | * 10: 1,2,5,10 17 | * 15: 1,3,5,15 18 | * 21: 1,3,7,21 19 | * 28: 1,2,4,7,14,28 20 | * 21 | * We can see that 28 is the first triangle number to have over five divisors. 22 | * What is the value of the first triangle number to have over five hundred divisors? 23 | * 24 | * @author ddaniel27 25 | */ 26 | package problem12 27 | 28 | func Problem12(limit uint) uint { 29 | triangle := uint(0) 30 | for i := uint(1); ; i++ { 31 | triangle += i 32 | if numDivisors(triangle) >= limit { 33 | return triangle 34 | } 35 | } 36 | } 37 | 38 | func numDivisors(n uint) uint { 39 | divisors := uint(0) 40 | for i := uint(1); i*i <= n; i++ { 41 | if n%i == 0 { 42 | divisors += 2 43 | } 44 | } 45 | return divisors 46 | } 47 | -------------------------------------------------------------------------------- /project_euler/problem_12/problem12_test.go: -------------------------------------------------------------------------------- 1 | package problem12 2 | 3 | import "testing" 4 | 5 | func TestProblem12_Func(t *testing.T) { 6 | tests := []struct { 7 | name string 8 | input uint 9 | want uint 10 | }{ 11 | {"Test Case 1", 6, 28}, 12 | {"Test Case 2", 7, 36}, 13 | {"Test Case 3", 11, 120}, 14 | {"Test Case 4", 500, 76576500}, 15 | } 16 | 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | actual := Problem12(tt.input) 20 | if actual != tt.want { 21 | t.Errorf("Expected: %v, but got %v", tt.want, actual) 22 | } 23 | }) 24 | } 25 | } 26 | 27 | func BenchmarkProblem12_Func(b *testing.B) { 28 | for i := 0; i < b.N; i++ { 29 | Problem12(500) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /project_euler/problem_13/problem13_test.go: -------------------------------------------------------------------------------- 1 | package problem13 2 | 3 | import "testing" 4 | 5 | func TestProblem13_Func(t *testing.T) { 6 | tests := []struct { 7 | name string 8 | expected string 9 | }{ 10 | {"Test Case 1", "5537376230"}, 11 | } 12 | 13 | for _, tt := range tests { 14 | t.Run(tt.name, func(t *testing.T) { 15 | actual := Problem13() 16 | if actual != tt.expected { 17 | t.Errorf("Expected: %v, but got %v", tt.expected, actual) 18 | } 19 | }) 20 | } 21 | } 22 | 23 | func BenchmarkProblem13_Func(b *testing.B) { 24 | for i := 0; i < b.N; i++ { 25 | Problem13() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /project_euler/problem_14/problem14_test.go: -------------------------------------------------------------------------------- 1 | package problem14 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem14_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input uint64 10 | want uint64 11 | }{ 12 | {"Input 30", 30, 27}, 13 | {"Input 1e6", 1e6, 837799}, 14 | } 15 | 16 | for _, tt := range tests { 17 | t.Run(tt.name, func(t *testing.T) { 18 | got := Problem14(tt.input) 19 | if got != tt.want { 20 | t.Errorf("Problem14() = %v, want %v", got, tt.want) 21 | } 22 | }) 23 | } 24 | } 25 | 26 | // Benchmarks 27 | func BenchmarkProblem14_Func(b *testing.B) { 28 | for i := 0; i < b.N; i++ { 29 | Problem14(1e6) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /project_euler/problem_15/problem15.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 15 - Lattice paths 3 | * @see {@link https://projecteuler.net/problem=15} 4 | * 5 | * Starting in the top left corner of a 2×2 grid, 6 | * and only being able to move to the right and down, 7 | * there are exactly 6 routes to the bottom right corner. 8 | * 9 | * How many such routes are there through a 20×20 grid? 10 | * 11 | * @author ddaniel27 12 | */ 13 | package problem15 14 | 15 | import ( 16 | "github.com/TheAlgorithms/Go/math/factorial" 17 | ) 18 | 19 | func Problem15(gridSize int) int { 20 | /** 21 | Author note: 22 | We can solve this problem using combinatorics. 23 | Here is a good blog post that explains the solution: 24 | 25 | [link](https://stemhash.com/counting-lattice-paths/) 26 | 27 | Btw, I'm not related to the author of the blog post. 28 | 29 | After some simplification, we can see that the solution is: 30 | (2n)! / (n!)^2 31 | 32 | We can use the factorial package to calculate the factorials. 33 | */ 34 | 35 | n := gridSize 36 | 37 | numerator, _ := factorial.Iterative(2 * n) 38 | denominator, _ := factorial.Iterative(n) 39 | denominator *= denominator 40 | 41 | return numerator / denominator 42 | } 43 | -------------------------------------------------------------------------------- /project_euler/problem_15/problem15_test.go: -------------------------------------------------------------------------------- 1 | package problem15 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem15_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input int 10 | want int 11 | }{ 12 | {"Input 2", 2, 6}, 13 | // This test case is disabled 14 | // because it needs a big integer to run successfully 15 | // and factorial package doesn't support it 16 | // {"Input 20", 20, 137846528820}, 17 | } 18 | 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | got := Problem15(tt.input) 22 | if got != tt.want { 23 | t.Errorf("Problem15() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | 29 | // Benchmarks 30 | func BenchmarkProblem15_Func(b *testing.B) { 31 | for i := 0; i < b.N; i++ { 32 | Problem15(20) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /project_euler/problem_16/problem16.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 16 - Power digit sum 3 | * @see {@link https://projecteuler.net/problem=16} 4 | * 5 | * 2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26. 6 | * 7 | * What is the sum of the digits of the number 2^1000? 8 | * 9 | * @author ddaniel27 10 | */ 11 | package problem16 12 | 13 | import ( 14 | "math/big" 15 | ) 16 | 17 | func Problem16(exponent int64) int64 { 18 | var result big.Int 19 | 20 | bigTwo := big.NewInt(2) 21 | bigExponent := big.NewInt(exponent) 22 | 23 | result.Exp(bigTwo, bigExponent, nil) 24 | 25 | resultStr := result.String() 26 | 27 | var sum int64 28 | for _, digit := range resultStr { 29 | sum += int64(digit - '0') 30 | } 31 | 32 | return sum 33 | } 34 | -------------------------------------------------------------------------------- /project_euler/problem_16/problem16_test.go: -------------------------------------------------------------------------------- 1 | package problem16 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem16_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | exponent int64 10 | want int64 11 | }{ 12 | {"2^15", 15, 26}, 13 | {"2^1000", 1000, 1366}, 14 | } 15 | 16 | for _, tt := range tests { 17 | t.Run(tt.name, func(t *testing.T) { 18 | if got := Problem16(tt.exponent); got != tt.want { 19 | t.Errorf("Problem16() = %v, want %v", got, tt.want) 20 | } 21 | }) 22 | } 23 | } 24 | 25 | // Benchmark 26 | func BenchmarkProblem16_Func(b *testing.B) { 27 | for i := 0; i < b.N; i++ { 28 | Problem16(1000) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /project_euler/problem_17/problem17.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 17 - Number letter counts 3 | * @see {@link https://projecteuler.net/problem=17} 4 | * 5 | * If the numbers 1 to 5 are written out in words: one, two, three, four, five, 6 | * then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total. 7 | * 8 | * If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, 9 | * how many letters would be used? 10 | * 11 | * NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) 12 | * contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. 13 | * The use of "and" when writing out numbers is in compliance with British usage. 14 | * 15 | * @author ddaniel27 16 | */ 17 | package problem17 18 | 19 | import "strings" 20 | 21 | func Problem17(input string) int { 22 | var sum int 23 | 24 | parsed := strings.Split(input, " ") 25 | 26 | for _, word := range parsed { 27 | sum += len(word) 28 | } 29 | 30 | return sum 31 | } 32 | -------------------------------------------------------------------------------- /project_euler/problem_17/problem17_test.go: -------------------------------------------------------------------------------- 1 | package problem17 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem17_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input string 10 | want int 11 | }{ 12 | {"1 to 5", "one two three four five", 19}, 13 | {"1 to 1000", INPUT, 21124}, 14 | } 15 | 16 | for _, tt := range tests { 17 | t.Run(tt.name, func(t *testing.T) { 18 | if got := Problem17(tt.input); got != tt.want { 19 | t.Errorf("Problem17() = %v, want %v", got, tt.want) 20 | } 21 | }) 22 | } 23 | } 24 | 25 | // Benchmark 26 | func BenchmarkProblem17_Func(b *testing.B) { 27 | for i := 0; i < b.N; i++ { 28 | Problem17(INPUT) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /project_euler/problem_18/input.go: -------------------------------------------------------------------------------- 1 | package problem18 2 | 3 | import "strings" 4 | 5 | const problem18_input_string = ` 6 | 75 7 | 95 64 8 | 17 47 82 9 | 18 35 87 10 10 | 20 04 82 47 65 11 | 19 01 23 75 03 34 12 | 88 02 77 73 07 63 67 13 | 99 65 04 28 06 16 70 92 14 | 41 41 26 56 83 40 80 70 33 15 | 41 48 72 33 47 32 37 16 94 29 16 | 53 71 44 65 25 43 91 52 97 51 14 17 | 70 11 33 28 77 73 17 78 39 68 17 57 18 | 91 71 52 38 17 14 91 43 58 50 27 29 48 19 | 63 66 04 68 89 53 67 30 73 16 69 87 40 31 20 | 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23 21 | ` 22 | 23 | var problem18_input_parsed_string []string = strings.Split( 24 | strings.Trim( 25 | strings.ReplaceAll(problem18_input_string, "\n", " "), 26 | " ", 27 | ), 28 | " ") 29 | 30 | const problem18_test_string = ` 31 | 3 32 | 7 4 33 | 2 4 6 34 | 8 5 9 3 35 | ` 36 | 37 | var problem18_test_parsed_string []string = strings.Split( 38 | strings.Trim( 39 | strings.ReplaceAll(problem18_test_string, "\n", " "), 40 | " ", 41 | ), 42 | " ") 43 | -------------------------------------------------------------------------------- /project_euler/problem_18/problem18_test.go: -------------------------------------------------------------------------------- 1 | package problem18 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem18_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input []string 10 | deep int 11 | expected int 12 | }{ 13 | { 14 | name: "Test case 1", 15 | input: problem18_test_parsed_string, 16 | deep: 2, 17 | expected: 23, 18 | }, 19 | { 20 | name: "Test case 2", 21 | input: problem18_input_parsed_string, 22 | deep: 2, 23 | expected: 1074, 24 | }, 25 | } 26 | 27 | for _, test := range tests { 28 | t.Run(test.name, func(t *testing.T) { 29 | actual := Problem18(test.input, test.deep) 30 | if actual != test.expected { 31 | t.Errorf("Expected %d, but got %d", test.expected, actual) 32 | } 33 | }) 34 | } 35 | } 36 | 37 | // Benchmarks 38 | func BenchmarkProblem18_Func(b *testing.B) { 39 | for i := 0; i < b.N; i++ { 40 | Problem18(problem18_input_parsed_string, 2) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /project_euler/problem_18/root.go: -------------------------------------------------------------------------------- 1 | package problem18 2 | 3 | type Root struct { 4 | ID int 5 | NodeValue NodeValue 6 | NodeLeft *Edge 7 | NodeRight *Edge 8 | } 9 | 10 | func (n *Root) Value() NodeValue { 11 | return n.NodeValue 12 | } 13 | 14 | func (n *Root) Left() Node { 15 | return n.NodeLeft 16 | } 17 | 18 | func (n *Root) Right() Node { 19 | return n.NodeRight 20 | } 21 | 22 | func (n *Root) Kind() string { 23 | return "root" 24 | } 25 | 26 | func (n *Root) CreateChild(value NodeValue, id int) Node { 27 | return &Edge{ 28 | ID: id, 29 | NodeValue: value, 30 | Parent: n, 31 | NodeLeft: nil, 32 | NodeRight: nil, 33 | } 34 | } 35 | 36 | func (n *Root) GetID() int { 37 | return n.ID 38 | } 39 | 40 | func (n *Root) Insert(node Node) { 41 | if n.NodeLeft == nil { 42 | n.NodeLeft = node.(*Edge) 43 | } else { 44 | n.NodeRight = node.(*Edge) 45 | } 46 | } 47 | 48 | func (n *Root) HasSpace() bool { 49 | return n.NodeLeft == nil || n.NodeRight == nil 50 | } 51 | 52 | func (n *Root) LeftIsNil() bool { 53 | return n.NodeLeft == nil 54 | } 55 | 56 | func (n *Root) RightIsNil() bool { 57 | return n.NodeRight == nil 58 | } 59 | 60 | func (n *Root) SetParent(node Node) { 61 | panic("Root node cannot have a parent") 62 | } 63 | -------------------------------------------------------------------------------- /project_euler/problem_19/problem19_test.go: -------------------------------------------------------------------------------- 1 | package problem19 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem19_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | expected int 10 | }{ 11 | {"Problem 19 - Counting Sundays", 171}, 12 | } 13 | 14 | for _, test := range tests { 15 | t.Run(test.name, func(t *testing.T) { 16 | got := Problem19() 17 | if got != test.expected { 18 | t.Errorf("Problem19() = got %v, want %v", got, test.expected) 19 | } 20 | }) 21 | } 22 | } 23 | 24 | // Benchmarks 25 | func BenchmarkProblem19_Func(b *testing.B) { 26 | for i := 0; i < b.N; i++ { 27 | Problem19() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /project_euler/problem_2/problem2.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 2 - Even Fibonacci numbers 3 | * @see {@link https://projecteuler.net/problem=2} 4 | * 5 | * Each new term in the Fibonacci sequence is generated by adding the previous two terms. 6 | * By starting with 1 and 2, the first 10 terms will be: 7 | * 8 | * 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... 9 | * 10 | * By considering the terms in the Fibonacci sequence whose values do not exceed four million, 11 | * find the sum of the even-valued terms. 12 | * 13 | * @author ddaniel27 14 | */ 15 | package problem2 16 | 17 | func Problem2(n uint) uint { 18 | sum := uint(0) 19 | a, b := uint(1), uint(2) 20 | 21 | for b < n { 22 | if b%2 == 0 { 23 | sum += b 24 | } 25 | 26 | a, b = b, a+b 27 | } 28 | 29 | return sum 30 | } 31 | -------------------------------------------------------------------------------- /project_euler/problem_2/problem2_test.go: -------------------------------------------------------------------------------- 1 | package problem2 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem2_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input uint 10 | want uint 11 | }{ 12 | { 13 | name: "Testcase 1 - input 10", 14 | input: 10, 15 | want: 10, 16 | }, 17 | { 18 | name: "Testcase 2 - input 100", 19 | input: 100, 20 | want: 44, 21 | }, 22 | { 23 | name: "Testcase 3 - input 4e6", 24 | input: 4e6, 25 | want: 4613732, 26 | }, 27 | } 28 | 29 | for _, tt := range tests { 30 | t.Run(tt.name, func(t *testing.T) { 31 | n := Problem2(tt.input) 32 | 33 | if n != tt.want { 34 | t.Errorf("Problem2() = %v, want %v", n, tt.want) 35 | } 36 | }) 37 | } 38 | } 39 | 40 | // Benchmarks 41 | func BenchmarkProblem2(b *testing.B) { 42 | for i := 0; i < b.N; i++ { 43 | _ = Problem2(4e6) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /project_euler/problem_20/problem20.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 20 - Factorial digit sum 3 | * @see {@link https://projecteuler.net/problem=20} 4 | * 5 | * n! means n × (n − 1) × ... × 3 × 2 × 1 6 | * 7 | * For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, 8 | * and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27. 9 | * 10 | * Find the sum of the digits in the number 100! 11 | * 12 | * @author ddaniel27 13 | */ 14 | package problem20 15 | 16 | import "math/big" 17 | 18 | func Problem20(input int) int { 19 | factorial := bigFactorial(input) 20 | sum := 0 21 | for _, digit := range factorial.String() { 22 | sum += int(digit - '0') 23 | } 24 | return sum 25 | } 26 | 27 | // bigFactorial returns the factorial of n as a big.Int 28 | // Use big package to handle large numbers 29 | func bigFactorial(n int) *big.Int { 30 | if n < 0 { 31 | return big.NewInt(0) 32 | } 33 | if n == 0 { 34 | return big.NewInt(1) 35 | } 36 | return big.NewInt(0).Mul(big.NewInt(int64(n)), bigFactorial(n-1)) 37 | } 38 | -------------------------------------------------------------------------------- /project_euler/problem_20/problem20_test.go: -------------------------------------------------------------------------------- 1 | package problem20 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem20_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input int 10 | expected int 11 | }{ 12 | {"Problem 20 - Factorial digit sum", 10, 27}, 13 | {"Problem 20 - Factorial digit sum", 100, 648}, 14 | } 15 | 16 | for _, test := range tests { 17 | t.Run(test.name, func(t *testing.T) { 18 | got := Problem20(test.input) 19 | if got != test.expected { 20 | t.Errorf("Problem20() = got %v, want %v", got, test.expected) 21 | } 22 | }) 23 | } 24 | } 25 | 26 | // Benchmarks 27 | func BenchmarkProblem20_Func(b *testing.B) { 28 | for i := 0; i < b.N; i++ { 29 | Problem20(100) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /project_euler/problem_3/problem3.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 3 - Largest prime factor 3 | * @see {@link https://projecteuler.net/problem=3} 4 | * 5 | * The prime factors of 13195 are 5, 7, 13 and 29. 6 | * What is the largest prime factor of the number 600851475143 ? 7 | * 8 | * @author ddaniel27 9 | */ 10 | package problem3 11 | 12 | func Problem3(n uint) uint { 13 | i := uint(2) 14 | 15 | for n > 1 { 16 | if n%i == 0 { 17 | n /= i 18 | } else { 19 | i++ 20 | } 21 | } 22 | 23 | return i 24 | } 25 | -------------------------------------------------------------------------------- /project_euler/problem_3/problem3_test.go: -------------------------------------------------------------------------------- 1 | package problem3 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem3_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input uint 10 | want uint 11 | }{ 12 | { 13 | name: "Testcase 1 - input 13195", 14 | input: 13195, 15 | want: 29, 16 | }, 17 | { 18 | name: "Testcase 2 - input 600851475143", 19 | input: 600851475143, 20 | want: 6857, 21 | }, 22 | } 23 | 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | n := Problem3(tt.input) 27 | 28 | if n != tt.want { 29 | t.Errorf("Problem3() = %v, want %v", n, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | 35 | // Benchmarks 36 | func BenchmarkProblem3(b *testing.B) { 37 | for i := 0; i < b.N; i++ { 38 | _ = Problem3(600851475143) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /project_euler/problem_4/problem4.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 4 - Largest palindrome product 3 | * @see {@link https://projecteuler.net/problem=4} 4 | * 5 | * A palindromic number reads the same both ways. 6 | * The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. 7 | * Find the largest palindrome made from the product of two 3-digit numbers. 8 | * 9 | * @author ddaniel27 10 | */ 11 | package problem4 12 | 13 | import ( 14 | "fmt" 15 | 16 | "github.com/TheAlgorithms/Go/strings/palindrome" 17 | ) 18 | 19 | func Problem4() uint { 20 | max := uint(0) 21 | 22 | for i := 999; i >= 100; i-- { 23 | for j := 999; j >= 100; j-- { 24 | n := uint(i * j) 25 | 26 | if palindrome.IsPalindrome(fmt.Sprintf("%d", n)) && n > max { 27 | max = n 28 | } 29 | } 30 | } 31 | 32 | return max 33 | } 34 | -------------------------------------------------------------------------------- /project_euler/problem_4/problem4_test.go: -------------------------------------------------------------------------------- 1 | package problem4 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem4_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | want uint 10 | }{ 11 | { 12 | name: "Testcase 1", 13 | want: 906609, 14 | }, 15 | } 16 | 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | n := Problem4() 20 | 21 | if n != tt.want { 22 | t.Errorf("Problem4() = %v, want %v", n, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | 28 | // Benchmarks 29 | func BenchmarkProblem4(b *testing.B) { 30 | for i := 0; i < b.N; i++ { 31 | _ = Problem4() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /project_euler/problem_5/problem5.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 5 - Smallest multiple 3 | * @see {@link https://projecteuler.net/problem=5} 4 | * 5 | * 2520 is the smallest number that can be divided by 6 | * each of the numbers from 1 to 10 without any remainder. 7 | * What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? 8 | * 9 | * @author ddaniel27 10 | */ 11 | package problem5 12 | 13 | func Problem5(limit uint) uint { 14 | n := limit * limit 15 | 16 | for { 17 | if isDivisible(n, limit) { 18 | return n 19 | } 20 | 21 | n++ 22 | } 23 | } 24 | 25 | func isDivisible(n, limit uint) bool { 26 | for i := uint(1); i <= limit; i++ { 27 | if n%i != 0 { 28 | return false 29 | } 30 | } 31 | 32 | return true 33 | } 34 | -------------------------------------------------------------------------------- /project_euler/problem_5/problem5_test.go: -------------------------------------------------------------------------------- 1 | package problem5 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem5_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input uint 10 | want uint 11 | }{ 12 | { 13 | name: "Testcase 1 - input 10", 14 | input: 10, 15 | want: 2520, 16 | }, 17 | { 18 | name: "Testcase 2 - input 20", 19 | input: 20, 20 | want: 232792560, 21 | }, 22 | { 23 | name: "Testcase 3 - input 5", 24 | input: 5, 25 | want: 60, 26 | }, 27 | } 28 | 29 | for _, tt := range tests { 30 | t.Run(tt.name, func(t *testing.T) { 31 | n := Problem5(tt.input) 32 | 33 | if n != tt.want { 34 | t.Errorf("Problem5() = %v, want %v", n, tt.want) 35 | } 36 | }) 37 | } 38 | } 39 | 40 | // Benchmarks 41 | func BenchmarkProblem5(b *testing.B) { 42 | for i := 0; i < b.N; i++ { 43 | _ = Problem5(20) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /project_euler/problem_6/problem6.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 6 - Sum square difference 3 | * @see {@link https://projecteuler.net/problem=6} 4 | * 5 | * The sum of the squares of the first ten natural numbers is, 6 | * 1^2 + 2^2 + ... + 10^2 = 385 7 | * 8 | * The square of the sum of the first ten natural numbers is, 9 | * (1 + 2 + ... + 10)^2 = 55^2 = 3025 10 | * 11 | * Hence the difference between the sum of the squares of the first ten natural numbers 12 | * and the square of the sum is 3025 − 385 = 2640. 13 | * 14 | * Find the difference between the sum of the squares of the first one hundred natural numbers 15 | * and the square of the sum. 16 | * 17 | * @author ddaniel27 18 | */ 19 | package problem6 20 | 21 | func Problem6(n uint) uint { 22 | sumOfSquares := uint(0) 23 | squareOfSum := uint(0) 24 | 25 | for i := uint(1); i <= n; i++ { 26 | sumOfSquares += i * i 27 | squareOfSum += i 28 | } 29 | 30 | squareOfSum *= squareOfSum 31 | 32 | return squareOfSum - sumOfSquares 33 | } 34 | -------------------------------------------------------------------------------- /project_euler/problem_6/problem6_test.go: -------------------------------------------------------------------------------- 1 | package problem6 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem6_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input uint 10 | want uint 11 | }{ 12 | { 13 | name: "Testcase 1 - input 10", 14 | input: 10, 15 | want: 2640, 16 | }, 17 | { 18 | name: "Testcase 2 - input 100", 19 | input: 100, 20 | want: 25164150, 21 | }, 22 | } 23 | 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | n := Problem6(tt.input) 27 | 28 | if n != tt.want { 29 | t.Errorf("Problem6() = %v, want %v", n, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | 35 | // Benchmarks 36 | func BenchmarkProblem6(b *testing.B) { 37 | for i := 0; i < b.N; i++ { 38 | _ = Problem6(100) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /project_euler/problem_7/problem7.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 7 - 10001st prime 3 | * @see {@link https://projecteuler.net/problem=7} 4 | * 5 | * By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, 6 | * we can see that the 6th prime is 13. 7 | * 8 | * What is the 10 001st prime number? 9 | * 10 | * @author ddaniel27 11 | */ 12 | package problem7 13 | 14 | import "github.com/TheAlgorithms/Go/math/prime" 15 | 16 | func Problem7(n uint) int64 { 17 | count, i := uint(0), int64(1) 18 | 19 | for count < n { 20 | i++ 21 | if prime.OptimizedTrialDivision(i) { 22 | count++ 23 | } 24 | } 25 | 26 | return i 27 | } 28 | -------------------------------------------------------------------------------- /project_euler/problem_7/problem7_test.go: -------------------------------------------------------------------------------- 1 | package problem7 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem7_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input uint 10 | want int64 11 | }{ 12 | { 13 | name: "Testcase 1 - input 6", 14 | input: 6, 15 | want: 13, 16 | }, 17 | { 18 | name: "Testcase 2 - input 10001", 19 | input: 10001, 20 | want: 104743, 21 | }, 22 | } 23 | 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | n := Problem7(tt.input) 27 | 28 | if n != tt.want { 29 | t.Errorf("Problem7() = %v, want %v", n, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | 35 | // Benchmarks 36 | func BenchmarkProblem7(b *testing.B) { 37 | for i := 0; i < b.N; i++ { 38 | _ = Problem7(10001) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /project_euler/problem_8/problem8_test.go: -------------------------------------------------------------------------------- 1 | package problem8 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem8_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | input int 10 | want uint 11 | }{ 12 | { 13 | name: "Testcase 1 - input 4", 14 | input: 4, 15 | want: 5832, 16 | }, 17 | { 18 | name: "Testcase 2 - input 13", 19 | input: 13, 20 | want: 23514624000, 21 | }, 22 | } 23 | 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | n := Problem8(tt.input) 27 | 28 | if n != tt.want { 29 | t.Errorf("Problem8() = %v, want %v", n, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | 35 | // Benchmarks 36 | func BenchmarkProblem8(b *testing.B) { 37 | for i := 0; i < b.N; i++ { 38 | _ = Problem8(13) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /project_euler/problem_9/problem9.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem 9 - Special Pythagorean triplet 3 | * @see {@link https://projecteuler.net/problem=9} 4 | * 5 | * A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, 6 | * a^2 + b^2 = c^2 7 | * 8 | * For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2. 9 | * 10 | * There exists exactly one Pythagorean triplet for which a + b + c = 1000. 11 | * Find the product abc. 12 | * 13 | * @author ddaniel27 14 | */ 15 | package problem9 16 | 17 | func Problem9() uint { 18 | for a := uint(1); a < 1000; a++ { 19 | for b := a + 1; b < 1000; b++ { 20 | c := 1000 - a - b 21 | 22 | if a*a+b*b == c*c { 23 | return a * b * c 24 | } 25 | } 26 | } 27 | 28 | return 0 29 | } 30 | -------------------------------------------------------------------------------- /project_euler/problem_9/problem9_test.go: -------------------------------------------------------------------------------- 1 | package problem9 2 | 3 | import "testing" 4 | 5 | // Tests 6 | func TestProblem9_Func(t *testing.T) { 7 | tests := []struct { 8 | name string 9 | want uint 10 | }{ 11 | { 12 | name: "Testcase 1", 13 | want: 31875000, 14 | }, 15 | } 16 | 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | n := Problem9() 20 | 21 | if n != tt.want { 22 | t.Errorf("Problem9() = %v, want %v", n, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | 28 | // Benchmarks 29 | func BenchmarkProblem9(b *testing.B) { 30 | for i := 0; i < b.N; i++ { 31 | _ = Problem9() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /search/doc.go: -------------------------------------------------------------------------------- 1 | // Package search is a subpackage dedicated to all searching algorithms related to slices/arrays. 2 | package search 3 | -------------------------------------------------------------------------------- /search/errors.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import "errors" 4 | 5 | // ErrNotFound is returned by search functions when target is not found 6 | var ErrNotFound = errors.New("target not found in array") 7 | -------------------------------------------------------------------------------- /search/interpolation_test.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import "testing" 4 | 5 | func TestInterpolation(t *testing.T) { 6 | for _, test := range searchTests { 7 | actualValue, actualError := Interpolation(test.data, test.key) 8 | if actualValue != test.expected { 9 | t.Errorf("test '%s' failed: input array '%v' with key '%d', expected '%d', get '%d'", test.name, test.data, test.key, test.expected, actualValue) 10 | } 11 | if actualError != test.expectedError { 12 | t.Errorf("test '%s' failed: input array '%v' with key '%d', expected error '%s', get error '%s'", test.name, test.data, test.key, test.expectedError, actualError) 13 | } 14 | } 15 | } 16 | 17 | func BenchmarkInterpolation(b *testing.B) { 18 | testCase := generateBenchmarkTestCase() 19 | b.ResetTimer() // exclude time taken to generate test case 20 | for i := 0; i < b.N; i++ { 21 | _, _ = Interpolation(testCase, i) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /search/jump2.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import "math" 4 | 5 | func Jump2(arr []int, target int) (int, error) { 6 | step := int(math.Round(math.Sqrt(float64(len(arr))))) 7 | rbound := len(arr) 8 | for i := step; i < len(arr); i += step { 9 | if arr[i] > target { 10 | rbound = i 11 | break 12 | } 13 | } 14 | 15 | for i := rbound - step; i < rbound; i++ { 16 | if arr[i] == target { 17 | return i, nil 18 | } 19 | if arr[i] > target { 20 | break 21 | } 22 | } 23 | return -1, ErrNotFound 24 | } 25 | -------------------------------------------------------------------------------- /search/jump2_test.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import "testing" 4 | 5 | func TestJump2(t *testing.T) { 6 | for _, test := range searchTests { 7 | actualValue, actualError := Jump2(test.data, test.key) 8 | if actualValue != test.expected { 9 | t.Errorf("test '%s' failed: input array '%v' with key '%d', expected '%d', get '%d'", test.name, test.data, test.key, test.expected, actualValue) 10 | } 11 | if actualError != test.expectedError { 12 | t.Errorf("test '%s' failed: input array '%v' with key '%d', expected error '%s', get error '%s'", test.name, test.data, test.key, test.expectedError, actualError) 13 | } 14 | } 15 | } 16 | 17 | func BenchmarkJump2(b *testing.B) { 18 | testCase := generateBenchmarkTestCase() 19 | b.ResetTimer() // exclude time taken to generate test case 20 | for i := 0; i < b.N; i++ { 21 | _, _ = Jump2(testCase, i) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /search/jump_test.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import "testing" 4 | 5 | func TestJump(t *testing.T) { 6 | for _, test := range searchTests { 7 | actualValue, actualError := Jump(test.data, test.key) 8 | if actualValue != test.expected { 9 | t.Errorf("test '%s' failed: input array '%v' with key '%d', expected '%d', get '%d'", test.name, test.data, test.key, test.expected, actualValue) 10 | } 11 | if actualError != test.expectedError { 12 | t.Errorf("test '%s' failed: input array '%v' with key '%d', expected error '%s', get error '%s'", test.name, test.data, test.key, test.expectedError, actualError) 13 | } 14 | } 15 | } 16 | 17 | func BenchmarkJump(b *testing.B) { 18 | testCase := generateBenchmarkTestCase() 19 | b.ResetTimer() // exclude time taken to generate test case 20 | for i := 0; i < b.N; i++ { 21 | _, _ = Jump(testCase, i) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /search/linear.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | // Linear Simple linear search algorithm that iterates over all elements of an array in the worst case scenario 4 | func Linear(array []int, query int) (int, error) { 5 | for i, item := range array { 6 | if item == query { 7 | return i, nil 8 | } 9 | } 10 | return -1, ErrNotFound 11 | } 12 | -------------------------------------------------------------------------------- /search/linear_test.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLinear(t *testing.T) { 8 | for _, test := range searchTests { 9 | actualValue, actualError := Linear(test.data, test.key) 10 | if actualValue != test.expected { 11 | t.Errorf("test '%s' failed: input array '%v' with key '%d', expected '%d', get '%d'", test.name, test.data, test.key, test.expected, actualValue) 12 | } 13 | if actualError != test.expectedError { 14 | t.Errorf("test '%s' failed: input array '%v' with key '%d', expected error '%s', get error '%s'", test.name, test.data, test.key, test.expectedError, actualError) 15 | } 16 | } 17 | } 18 | 19 | func BenchmarkLinear(b *testing.B) { 20 | testCase := generateBenchmarkTestCase() 21 | b.ResetTimer() // exclude time taken to generate test case 22 | for i := 0; i < b.N; i++ { 23 | _, _ = Linear(testCase, i) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /search/selectk.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | func SelectK(array []int, k int) (int, error) { 4 | if k > len(array) { 5 | return -1, ErrNotFound 6 | } 7 | return selectK(array, 0, len(array), len(array)-k), nil 8 | } 9 | 10 | // search the element which index is idx 11 | func selectK(array []int, l, r, idx int) int { 12 | index := partition(array, l, r) 13 | if index == idx { 14 | return array[index] 15 | } 16 | if index < idx { 17 | return selectK(array, index+1, r, idx) 18 | } 19 | return selectK(array, l, index, idx) 20 | } 21 | 22 | func partition(array []int, l, r int) int { 23 | elem, j := array[l], l+1 24 | for i := l + 1; i < r; i++ { 25 | if array[i] <= elem { 26 | array[i], array[j] = array[j], array[i] 27 | j++ 28 | } 29 | } 30 | array[l], array[j-1] = array[j-1], array[l] 31 | return j - 1 32 | } 33 | -------------------------------------------------------------------------------- /search/selectk_test.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSelectK(t *testing.T) { 8 | tests := []struct { 9 | data []int 10 | k int 11 | expected int 12 | err error 13 | name string 14 | }{ 15 | {[]int{1, 2, 3, 4, 5}, 1, 5, nil, "sorted data"}, 16 | {[]int{5, 4, 3, 2, 1}, 2, 4, nil, "reversed data"}, 17 | {[]int{3, 1, 2, 5, 4}, 3, 3, nil, "random data"}, 18 | {[]int{3, 2, 1, 5, 4}, 10, -1, ErrNotFound, " absent data"}, 19 | } 20 | for _, tc := range tests { 21 | t.Run(tc.name, func(t *testing.T) { 22 | elem, err := SelectK(tc.data, tc.k) 23 | if err != tc.err { 24 | t.Errorf("name:%v SelectK() = _, %v, want err: %v", tc.name, err, tc.err) 25 | } 26 | if elem != tc.expected { 27 | t.Errorf("name:%v SelectK() = %v,_ , want: %v", tc.name, elem, tc.expected) 28 | } 29 | }) 30 | } 31 | } 32 | 33 | func BenchmarkSelectK(b *testing.B) { 34 | testCase := generateBenchmarkTestCase() 35 | testCase = append(testCase, 1) // make sure len(testCase)/2+1 is valid 36 | b.ResetTimer() 37 | 38 | for i := 0; i < b.N; i++ { 39 | _, _ = SelectK(testCase, len(testCase)/2) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /sort/binaryinsertionsort.go: -------------------------------------------------------------------------------- 1 | // Binary Insertion Sort 2 | // description: Implementation of binary insertion sort in Go 3 | // details: Binary Insertion Sort is a variation of 4 | // Insertion sort in which proper location to 5 | // insert the selected element is found using the 6 | // Binary search algorithm. 7 | // ref: https://www.geeksforgeeks.org/binary-insertion-sort 8 | 9 | package sort 10 | 11 | import "github.com/TheAlgorithms/Go/constraints" 12 | 13 | func BinaryInsertion[T constraints.Ordered](arr []T) []T { 14 | for currentIndex := 1; currentIndex < len(arr); currentIndex++ { 15 | temporary := arr[currentIndex] 16 | low := 0 17 | high := currentIndex - 1 18 | 19 | for low <= high { 20 | mid := low + (high-low)/2 21 | if arr[mid] > temporary { 22 | high = mid - 1 23 | } else { 24 | low = mid + 1 25 | } 26 | } 27 | 28 | for itr := currentIndex; itr > low; itr-- { 29 | arr[itr] = arr[itr-1] 30 | } 31 | 32 | arr[low] = temporary 33 | } 34 | return arr 35 | } 36 | -------------------------------------------------------------------------------- /sort/bogosort.go: -------------------------------------------------------------------------------- 1 | // This is a pure Go implementation of the bogosort algorithm, 2 | // also known as permutation sort, stupid sort, slowsort, shotgun sort, or monkey sort. 3 | // Bogosort generates random permutations until it guesses the correct one. 4 | // worst-case time complexity: O((n+1)!) 5 | // best-case time complexity: O(n) 6 | // More info on: https://en.wikipedia.org/wiki/Bogosort 7 | 8 | package sort 9 | 10 | import ( 11 | "math/rand" 12 | 13 | "github.com/TheAlgorithms/Go/constraints" 14 | ) 15 | 16 | func isSorted[T constraints.Number](arr []T) bool { 17 | for i := 0; i < len(arr)-1; i++ { 18 | if arr[i] > arr[i+1] { 19 | return false 20 | } 21 | } 22 | 23 | return true 24 | } 25 | 26 | func shuffle[T constraints.Number](arr []T) { 27 | for i := range arr { 28 | j := rand.Intn(i + 1) 29 | arr[i], arr[j] = arr[j], arr[i] 30 | } 31 | } 32 | 33 | func Bogo[T constraints.Number](arr []T) []T { 34 | for !isSorted(arr) { 35 | shuffle(arr) 36 | } 37 | 38 | return arr 39 | } 40 | -------------------------------------------------------------------------------- /sort/bubblesort.go: -------------------------------------------------------------------------------- 1 | // Implementation of basic bubble sort algorithm 2 | // Reference: https://en.wikipedia.org/wiki/Bubble_sort 3 | 4 | package sort 5 | 6 | import "github.com/TheAlgorithms/Go/constraints" 7 | 8 | // Bubble is a simple generic definition of Bubble sort algorithm. 9 | func Bubble[T constraints.Ordered](arr []T) []T { 10 | swapped := true 11 | for swapped { 12 | swapped = false 13 | for i := 0; i < len(arr)-1; i++ { 14 | if arr[i+1] < arr[i] { 15 | arr[i+1], arr[i] = arr[i], arr[i+1] 16 | swapped = true 17 | } 18 | } 19 | } 20 | return arr 21 | } 22 | -------------------------------------------------------------------------------- /sort/bucketsort.go: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import "github.com/TheAlgorithms/Go/constraints" 4 | 5 | // Bucket sorts a slice. It is mainly useful 6 | // when input is uniformly distributed over a range. 7 | func Bucket[T constraints.Number](arr []T) []T { 8 | // early return if the array too small 9 | if len(arr) <= 1 { 10 | return arr 11 | } 12 | 13 | // find the maximum and minimum elements in arr 14 | max := arr[0] 15 | min := arr[0] 16 | for _, v := range arr { 17 | if v > max { 18 | max = v 19 | } 20 | if v < min { 21 | min = v 22 | } 23 | } 24 | 25 | // create an empty bucket for each element in arr 26 | bucket := make([][]T, len(arr)) 27 | 28 | // put each element in the appropriate bucket 29 | for _, v := range arr { 30 | bucketIndex := int((v - min) / (max - min) * T(len(arr)-1)) 31 | bucket[bucketIndex] = append(bucket[bucketIndex], v) 32 | } 33 | 34 | // use insertion sort to sort each bucket 35 | for i := range bucket { 36 | bucket[i] = Insertion(bucket[i]) 37 | } 38 | 39 | // concatenate the sorted buckets 40 | sorted := make([]T, 0, len(arr)) 41 | for _, v := range bucket { 42 | sorted = append(sorted, v...) 43 | } 44 | 45 | return sorted 46 | } 47 | -------------------------------------------------------------------------------- /sort/circlesort.go: -------------------------------------------------------------------------------- 1 | // Package sort implements various sorting algorithms. 2 | package sort 3 | 4 | import "github.com/TheAlgorithms/Go/constraints" 5 | 6 | // Circle sorts an array using the circle sort algorithm. 7 | func Circle[T constraints.Ordered](arr []T) []T { 8 | if len(arr) == 0 { 9 | return arr 10 | } 11 | for doSort(arr, 0, len(arr)-1) { 12 | } 13 | return arr 14 | } 15 | 16 | // doSort is the recursive function that implements the circle sort algorithm. 17 | func doSort[T constraints.Ordered](arr []T, left, right int) bool { 18 | if left == right { 19 | return false 20 | } 21 | swapped := false 22 | low := left 23 | high := right 24 | 25 | for low < high { 26 | if arr[low] > arr[high] { 27 | arr[low], arr[high] = arr[high], arr[low] 28 | swapped = true 29 | } 30 | low++ 31 | high-- 32 | } 33 | 34 | if low == high && arr[low] > arr[high+1] { 35 | arr[low], arr[high+1] = arr[high+1], arr[low] 36 | swapped = true 37 | } 38 | 39 | mid := left + (right-left)/2 40 | leftHalf := doSort(arr, left, mid) 41 | rightHalf := doSort(arr, mid+1, right) 42 | 43 | return swapped || leftHalf || rightHalf 44 | } 45 | -------------------------------------------------------------------------------- /sort/combSort.go: -------------------------------------------------------------------------------- 1 | // Implementation of comb sort algorithm, an improvement of bubble sort 2 | // average time complexity: O(n^2 / 2^p) where p is the number of increments 3 | // worst time complexity: O(n^2) 4 | // space complexity: O(1) 5 | // Reference: https://www.geeksforgeeks.org/comb-sort/ 6 | 7 | package sort 8 | 9 | import "github.com/TheAlgorithms/Go/constraints" 10 | 11 | func getNextGap(gap int) int { 12 | gap = (gap * 10) / 13 13 | if gap < 1 { 14 | return 1 15 | } 16 | return gap 17 | } 18 | 19 | // Comb is a simple sorting algorithm which is an improvement of the bubble sorting algorithm. 20 | func Comb[T constraints.Ordered](data []T) []T { 21 | n := len(data) 22 | gap := n 23 | swapped := true 24 | 25 | for gap != 1 || swapped { 26 | gap = getNextGap(gap) 27 | swapped = false 28 | for i := 0; i < n-gap; i++ { 29 | if data[i] > data[i+gap] { 30 | data[i], data[i+gap] = data[i+gap], data[i] 31 | swapped = true 32 | } 33 | } 34 | } 35 | return data 36 | } 37 | -------------------------------------------------------------------------------- /sort/countingsort.go: -------------------------------------------------------------------------------- 1 | // countingsort.go 2 | // description: Implementation of counting sort algorithm 3 | // details: A simple counting sort algorithm implementation 4 | // worst-case time complexity: O(n + k) where n is the number of elements in the input array and k is the range of the input 5 | // average-case time complexity: O(n + k) where n is the number of elements in the input array and k is the range of the input 6 | // space complexity: O(n + k) 7 | // author [Phil](https://github.com/pschik) 8 | // see sort_test.go for a test implementation, test function TestQuickSort 9 | 10 | package sort 11 | 12 | import "github.com/TheAlgorithms/Go/constraints" 13 | 14 | func Count[T constraints.Integer](data []T) []T { 15 | if len(data) == 0 { 16 | return data 17 | } 18 | var aMin, aMax = data[0], data[0] 19 | for _, x := range data { 20 | if x < aMin { 21 | aMin = x 22 | } 23 | if x > aMax { 24 | aMax = x 25 | } 26 | } 27 | count := make([]int, aMax-aMin+1) 28 | for _, x := range data { 29 | count[x-aMin]++ // this is the reason for having only Integer constraint instead of Ordered. 30 | } 31 | z := 0 32 | for i, c := range count { 33 | for c > 0 { 34 | data[z] = T(i) + aMin 35 | z++ 36 | c-- 37 | } 38 | } 39 | return data 40 | } 41 | -------------------------------------------------------------------------------- /sort/doc.go: -------------------------------------------------------------------------------- 1 | // Package sort a package for demonstrating sorting algorithms in Go 2 | package sort 3 | -------------------------------------------------------------------------------- /sort/exchangesort.go: -------------------------------------------------------------------------------- 1 | // Implementation of exchange sort algorithm, a variant of bubble sort 2 | // average time complexity: O(n^2) 3 | // worst time complexity: O(n^2) 4 | // space complexity: O(1) 5 | // Reference: https://en.wikipedia.org/wiki/Sorting_algorithm#Exchange_sort 6 | 7 | package sort 8 | 9 | import "github.com/TheAlgorithms/Go/constraints" 10 | 11 | func Exchange[T constraints.Ordered](arr []T) []T { 12 | for i := 0; i < len(arr)-1; i++ { 13 | for j := i + 1; j < len(arr); j++ { 14 | if arr[i] > arr[j] { 15 | arr[i], arr[j] = arr[j], arr[i] 16 | } 17 | } 18 | } 19 | 20 | return arr 21 | } 22 | -------------------------------------------------------------------------------- /sort/insertionsort.go: -------------------------------------------------------------------------------- 1 | // insertionsort.go 2 | // description: Implementation of insertion sort algorithm 3 | // worst-case time complexity: O(n^2) 4 | // average-case time complexity: O(n^2) 5 | // space complexity: O(1) 6 | 7 | package sort 8 | 9 | import "github.com/TheAlgorithms/Go/constraints" 10 | 11 | func Insertion[T constraints.Ordered](arr []T) []T { 12 | for currentIndex := 1; currentIndex < len(arr); currentIndex++ { 13 | temporary := arr[currentIndex] 14 | iterator := currentIndex 15 | for ; iterator > 0 && arr[iterator-1] > temporary; iterator-- { 16 | arr[iterator] = arr[iterator-1] 17 | } 18 | arr[iterator] = temporary 19 | } 20 | return arr 21 | } 22 | -------------------------------------------------------------------------------- /sort/oddevensort.go: -------------------------------------------------------------------------------- 1 | // oddevensort.go 2 | // Implementation of Odd-Even Sort (Brick Sort) 3 | // Reference: https://en.wikipedia.org/wiki/Odd%E2%80%93even_sort 4 | 5 | package sort 6 | 7 | import "github.com/TheAlgorithms/Go/constraints" 8 | 9 | // OddEvenSort performs the odd-even sort algorithm on the given array. 10 | // It is a variation of bubble sort that compares adjacent pairs, alternating 11 | // between odd and even indexed elements in each pass until the array is sorted. 12 | func OddEvenSort[T constraints.Ordered](arr []T) []T { 13 | if len(arr) == 0 { // handle empty array 14 | return arr 15 | } 16 | 17 | swapped := true 18 | for swapped { 19 | swapped = false 20 | 21 | // Perform "odd" indexed pass 22 | for i := 1; i < len(arr)-1; i += 2 { 23 | if arr[i] > arr[i+1] { 24 | arr[i], arr[i+1] = arr[i+1], arr[i] 25 | swapped = true 26 | } 27 | } 28 | 29 | // Perform "even" indexed pass 30 | for i := 0; i < len(arr)-1; i += 2 { 31 | if arr[i] > arr[i+1] { 32 | arr[i], arr[i+1] = arr[i+1], arr[i] 33 | swapped = true 34 | } 35 | } 36 | } 37 | 38 | return arr 39 | } 40 | -------------------------------------------------------------------------------- /sort/pancakesort.go: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import "github.com/TheAlgorithms/Go/constraints" 4 | 5 | // Pancake sorts a slice using flip operations, 6 | // where flip refers to the idea of reversing the 7 | // slice from index `0` to `i`. 8 | func Pancake[T constraints.Ordered](arr []T) []T { 9 | // early return if the array too small 10 | if len(arr) <= 1 { 11 | return arr 12 | } 13 | 14 | // start from the end of the array 15 | for i := len(arr) - 1; i > 0; i-- { 16 | // find the index of the maximum element in arr 17 | max := 0 18 | for j := 1; j <= i; j++ { 19 | if arr[j] > arr[max] { 20 | max = j 21 | } 22 | } 23 | 24 | // if the maximum element is not at the end of the array 25 | if max != i { 26 | // flip the maximum element to the beginning of the array 27 | arr = flip(arr, max) 28 | 29 | // flip the maximum element to the end of the array by flipping the whole array 30 | arr = flip(arr, i) 31 | } 32 | } 33 | 34 | return arr 35 | } 36 | 37 | // flip reverses the input slice from `0` to `i`. 38 | func flip[T constraints.Ordered](arr []T, i int) []T { 39 | for j := 0; j < i; j++ { 40 | arr[j], arr[i] = arr[i], arr[j] 41 | i-- 42 | } 43 | return arr 44 | } 45 | -------------------------------------------------------------------------------- /sort/pigeonholesort.go: -------------------------------------------------------------------------------- 1 | // Pigeonhole algorithm's working at wikipedia. 2 | // https://en.wikipedia.org/wiki/Pigeonhole_sort 3 | // time complexity: O(n + N) where n is the number of elements in the array and N is the range of input 4 | // space complexity: O(N) 5 | 6 | package sort 7 | 8 | import ( 9 | "github.com/TheAlgorithms/Go/constraints" 10 | "github.com/TheAlgorithms/Go/math/max" 11 | "github.com/TheAlgorithms/Go/math/min" 12 | ) 13 | 14 | // Pigeonhole sorts a slice using pigeonhole sorting algorithm. 15 | // NOTE: To maintain time complexity O(n + N), this is the reason for having 16 | // only Integer constraint instead of Ordered. 17 | func Pigeonhole[T constraints.Integer](arr []T) []T { 18 | if len(arr) == 0 { 19 | return arr 20 | } 21 | 22 | max := max.Int(arr...) 23 | min := min.Int(arr...) 24 | 25 | size := max - min + 1 26 | 27 | holes := make([]T, size) 28 | 29 | for _, element := range arr { 30 | holes[element-min]++ 31 | } 32 | 33 | i := 0 34 | 35 | for j := T(0); j < size; j++ { 36 | for holes[j] > 0 { 37 | holes[j]-- 38 | arr[i] = j + min 39 | i++ 40 | } 41 | } 42 | 43 | return arr 44 | } 45 | -------------------------------------------------------------------------------- /sort/selectionsort.go: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import "github.com/TheAlgorithms/Go/constraints" 4 | 5 | func Selection[T constraints.Ordered](arr []T) []T { 6 | for i := 0; i < len(arr); i++ { 7 | min := i 8 | for j := i + 1; j < len(arr); j++ { 9 | if arr[j] < arr[min] { 10 | min = j 11 | } 12 | } 13 | 14 | arr[i], arr[min] = arr[min], arr[i] 15 | } 16 | return arr 17 | } 18 | -------------------------------------------------------------------------------- /sort/shellsort.go: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import "github.com/TheAlgorithms/Go/constraints" 4 | 5 | func Shell[T constraints.Ordered](arr []T) []T { 6 | for d := int(len(arr) / 2); d > 0; d /= 2 { 7 | for i := d; i < len(arr); i++ { 8 | for j := i; j >= d && arr[j-d] > arr[j]; j -= d { 9 | arr[j], arr[j-d] = arr[j-d], arr[j] 10 | } 11 | } 12 | } 13 | return arr 14 | } 15 | -------------------------------------------------------------------------------- /sort/stooge_sort.go: -------------------------------------------------------------------------------- 1 | // implementation of the Stooge sort 2 | // more info at https://en.wikipedia.org/wiki/Stooge_sort 3 | // worst-case time complexity O(n^2.709511) 4 | // worst-case space complexity O(n) 5 | 6 | package sort 7 | 8 | import ( 9 | "github.com/TheAlgorithms/Go/constraints" 10 | 11 | // math imported for floor division 12 | "math" 13 | ) 14 | 15 | func innerStooge[T constraints.Ordered](arr []T, i int32, j int32) []T { 16 | if arr[i] > arr[j] { 17 | arr[i], arr[j] = arr[j], arr[i] 18 | } 19 | if (j - i + 1) > 2 { 20 | t := int32(math.Floor(float64(j-i+1) / 3.0)) 21 | arr = innerStooge(arr, i, j-t) 22 | arr = innerStooge(arr, i+t, j) 23 | arr = innerStooge(arr, i, j-t) 24 | } 25 | return arr 26 | } 27 | 28 | func Stooge[T constraints.Ordered](arr []T) []T { 29 | if len(arr) == 0 { 30 | return arr 31 | } 32 | 33 | return innerStooge(arr, 0, int32(len(arr)-1)) 34 | } 35 | -------------------------------------------------------------------------------- /strings/ahocorasick/ahocorasick_test.go: -------------------------------------------------------------------------------- 1 | package ahocorasick 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "strings" 7 | "testing" 8 | ) 9 | 10 | func TestAhoCorasick(t *testing.T) { 11 | for _, tc := range testCases { 12 | t.Run(tc.name, func(t *testing.T) { 13 | actual := AhoCorasick(tc.text, tc.words) 14 | if !reflect.DeepEqual(actual, tc.expected) { 15 | actualString := convertToString(actual) 16 | expectedString := convertToString(tc.expected) 17 | t.Errorf("Expected matches for patterns %s for string '%s' are: patterns and positions found %v, but actual matches are: patterns and positions found %v", 18 | tc.words, tc.text, actualString, expectedString) 19 | } 20 | }) 21 | } 22 | } 23 | 24 | func convertToString(res Result) string { 25 | var r strings.Builder 26 | for key, val := range res.occurrences { 27 | r.WriteString(fmt.Sprintf("Word: '%s' at positions: ", key)) 28 | for i := range val { 29 | r.WriteString(fmt.Sprintf("%d", val[i])) 30 | if i != len(val)-1 { 31 | r.WriteString(", ") 32 | } 33 | } 34 | r.WriteString(". ") 35 | } 36 | return r.String() 37 | } 38 | -------------------------------------------------------------------------------- /strings/ahocorasick/patterns.txt: -------------------------------------------------------------------------------- 1 | announce annual annually -------------------------------------------------------------------------------- /strings/ahocorasick/text.txt: -------------------------------------------------------------------------------- 1 | CPM_annual_conference_announce -------------------------------------------------------------------------------- /strings/charoccurrence.go: -------------------------------------------------------------------------------- 1 | // charoccurrence.go 2 | // description: An algorithm which counts the number 3 | // of times a character occurred in a string. 4 | // author(s) [Moein](https://github.com/mo1ein) 5 | // see charoccurrence_test.go 6 | 7 | package strings 8 | 9 | // CountChars counts the number of a times a character 10 | // has occurred in the provided string argument and 11 | // returns a map with `rune` as keys and the count as value. 12 | func CountChars(text string) map[rune]int { 13 | charMap := make(map[rune]int, 0) 14 | for _, c := range text { 15 | if _, ok := charMap[c]; !ok { 16 | charMap[c] = 0 17 | } 18 | charMap[c]++ 19 | } 20 | return charMap 21 | } 22 | -------------------------------------------------------------------------------- /strings/charoccurrence_test.go: -------------------------------------------------------------------------------- 1 | package strings_test 2 | 3 | import ( 4 | "github.com/TheAlgorithms/Go/strings" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestCountChars(t *testing.T) { 10 | var testCases = []struct { 11 | name string 12 | input string 13 | expected map[rune]int 14 | }{ 15 | { 16 | "english text", 17 | "hello world!", 18 | map[rune]int{32: 1, 33: 1, 100: 1, 101: 1, 104: 1, 108: 3, 111: 2, 114: 1, 119: 1}, 19 | }, 20 | { 21 | "chinese text", 22 | " 世界 ", 23 | map[rune]int{32: 2, 19990: 1, 30028: 1}, 24 | }, 25 | { 26 | "persian text", 27 | "سلام دنیا!", 28 | map[rune]int{32: 1, 33: 1, 1575: 2, 1583: 1, 1587: 1, 1604: 1, 1605: 1, 1606: 1, 1740: 1}, 29 | }, 30 | } 31 | for _, test := range testCases { 32 | t.Run(test.name, func(t *testing.T) { 33 | funcResult := strings.CountChars(test.input) 34 | if !reflect.DeepEqual(test.expected, funcResult) { 35 | t.Errorf("expected: %v, got %v", test.expected, funcResult) 36 | } 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /strings/combination/combination.go: -------------------------------------------------------------------------------- 1 | // Package combination ... 2 | package combination 3 | 4 | import "fmt" 5 | 6 | // Combinations structure with in and out rune 7 | type Combinations struct { 8 | out []rune 9 | in []rune 10 | } 11 | 12 | // Start ... 13 | func Start(input string) { 14 | c := &Combinations{ 15 | in: []rune(input), 16 | } 17 | 18 | c.Combine(0) 19 | } 20 | 21 | // Combine ... 22 | func (c *Combinations) Combine(seed int) { 23 | inLen := len(c.in) 24 | for i := seed; i < inLen-1; i++ { 25 | c.out = append(c.out, c.in[i]) 26 | fmt.Println(string(c.out)) 27 | c.Combine(i + 1) 28 | c.out = c.out[:len(c.out)-1] 29 | } 30 | c.out = append(c.out, c.in[inLen-1]) 31 | fmt.Println(string(c.out)) 32 | c.out = c.out[:len(c.out)-1] 33 | } 34 | -------------------------------------------------------------------------------- /strings/doc.go: -------------------------------------------------------------------------------- 1 | // Package strings is a package that contains all algorithms 2 | // that are used to analyse and manipulate strings. 3 | package strings 4 | -------------------------------------------------------------------------------- /strings/generateparentheses/generateparentheses.go: -------------------------------------------------------------------------------- 1 | // generateparenthesesgo 2 | // description: Generate Parentheses 3 | // details: 4 | // Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. 5 | // author(s) [red_byte](https://github.com/i-redbyte) 6 | // see generateparentheses_test.go 7 | 8 | package generateparentheses 9 | 10 | import "strings" 11 | 12 | func GenerateParenthesis(n int) []string { 13 | result := make([]string, 0) 14 | maxLen := 2 * n 15 | var recursiveComputation func(s []string, left int, right int) 16 | recursiveComputation = func(s []string, left int, right int) { 17 | if len(s) == maxLen { 18 | result = append(result, strings.Join(s, "")) 19 | return 20 | } 21 | if left < n { 22 | s = append(s, "(") 23 | recursiveComputation(s, left+1, right) 24 | s = s[:len(s)-1] 25 | } 26 | if right < left { 27 | s = append(s, ")") 28 | recursiveComputation(s, left, right+1) 29 | _ = s[:len(s)-1] 30 | } 31 | } 32 | recursiveComputation(make([]string, 0), 0, 0) 33 | return result 34 | } 35 | -------------------------------------------------------------------------------- /strings/generateparentheses/generateparentheses_test.go: -------------------------------------------------------------------------------- 1 | // generateparentheses_test.go 2 | // description: Generate Parentheses 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see generateparentheses.go 5 | 6 | package generateparentheses 7 | 8 | import "testing" 9 | 10 | func TestGenerateParenthesis(t *testing.T) { 11 | t.Run("GenerateParenthesis", func(t *testing.T) { 12 | result := GenerateParenthesis(3) 13 | t.Log(result) 14 | exp := []string{"((()))", "(()())", "(())()", "()(())", "()()()"} 15 | for i, v := range result { 16 | if v != exp[i] { 17 | t.Errorf("Wrong result! Expected:%s, returned:%s ", result[i], exp[i]) 18 | } 19 | } 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /strings/genetic/geneticalgorithm_test.go: -------------------------------------------------------------------------------- 1 | package genetic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSimple(t *testing.T) { 8 | target := "This is a genetic algorithm to evaluate, combine, evolve and mutate a string!" 9 | charmap := []rune(" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,;!?+-*#@^'èéòà€ù=)(&%$£/\\") 10 | 11 | res, err := GeneticString(target, charmap, &Conf{}) 12 | if err != nil { 13 | t.Errorf("Unexpected error: %v\n", err) 14 | } 15 | 16 | got := res.Best 17 | 18 | if got.Value != float64(1.0) { 19 | t.Errorf("Target value not reached\nwant: %f\n, got: %f\n", float64(1.0), got.Value) 20 | } 21 | 22 | if got.Key != target { 23 | t.Errorf("Target string not reached\nwant: %s\n, got: %s\n", target, got.Key) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /strings/hamming/hammingdistance.go: -------------------------------------------------------------------------------- 1 | /* 2 | This algorithm calculates the hamming distance between two equal length strings. 3 | The Hamming distance between two equal-length strings of symbols is the number of positions 4 | at which the corresponding symbols are different: 5 | https://en.wikipedia.org/wiki/Hamming_distance 6 | 7 | Note that we didn't consider strings as an array of bytes, therefore, we didn't use the XOR operator. 8 | In this case, we used a simple loop to compare each character of the strings, and if they are different, 9 | we increment the hamming distance by 1. 10 | 11 | Parameters: two strings to compare 12 | Output: distance between both strings */ 13 | 14 | package hamming 15 | 16 | import "errors" 17 | 18 | func Distance(str1, str2 string) (int, error) { 19 | if len(str1) != len(str2) { 20 | return -1, errors.New("strings must have a same length") 21 | } 22 | 23 | hammingDistance := 0 24 | for i := 0; i < len(str1); i++ { 25 | if str1[i] != str2[i] { 26 | hammingDistance++ 27 | } 28 | } 29 | 30 | return hammingDistance, nil 31 | } 32 | -------------------------------------------------------------------------------- /strings/hamming/hammingdistance_test.go: -------------------------------------------------------------------------------- 1 | package hamming 2 | 3 | import "testing" 4 | 5 | var testCases = []struct { 6 | name string 7 | string1 string 8 | string2 string 9 | expected int 10 | }{ 11 | { 12 | "empty strings", 13 | "", 14 | "", 15 | 0, 16 | }, 17 | { 18 | "single character strings", 19 | "A", 20 | "A", 21 | 0, 22 | }, 23 | { 24 | "two different strings with a same length", 25 | "TestString 1", 26 | "TestString 2", 27 | 1, 28 | }, 29 | { 30 | "two different strings with a different length", 31 | "TestString1", 32 | "TestString", 33 | -1, 34 | }, 35 | { 36 | "two same strings with a same length", 37 | "TestString", 38 | "TestString", 39 | 0, 40 | }, 41 | } 42 | 43 | func TestHammingDistance(t *testing.T) { 44 | for _, tc := range testCases { 45 | t.Run(tc.name, func(t *testing.T) { 46 | actual, err := Distance(tc.string1, tc.string2) 47 | if err != nil { 48 | if tc.expected != -1 { 49 | t.Fatalf("Expected no error, but got %v", err) 50 | } 51 | } else if actual != tc.expected { 52 | t.Errorf("Expected Hamming distance between strings: '%s' and '%s' is %v, but got: %v", tc.string1, tc.string2, tc.expected, actual) 53 | } 54 | }) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /strings/issubsequence.go: -------------------------------------------------------------------------------- 1 | // Checks if a given string is a subsequence of another string. 2 | // A subsequence of a given string is a string that can be derived from the given 3 | // string by deleting some or no characters without changing the order of the 4 | // remaining characters. (i.e., "dpr" is a subsequence of "depqr" while "drp" is not). 5 | // Author: sanjibgirics 6 | 7 | package strings 8 | 9 | // Returns true if s is subsequence of t, otherwise return false. 10 | func IsSubsequence(s string, t string) bool { 11 | if len(s) > len(t) { 12 | return false 13 | } 14 | 15 | if s == t { 16 | return true 17 | } 18 | 19 | if len(s) == 0 { 20 | return true 21 | } 22 | 23 | sIndex := 0 24 | for tIndex := 0; tIndex < len(t); tIndex++ { 25 | if s[sIndex] == t[tIndex] { 26 | sIndex++ 27 | } 28 | 29 | if sIndex == len(s) { 30 | return true 31 | } 32 | } 33 | 34 | return false 35 | } 36 | -------------------------------------------------------------------------------- /strings/kmp/kmp.go: -------------------------------------------------------------------------------- 1 | package kmp 2 | 3 | // Kmp Function kmp performing the Knuth-Morris-Pratt algorithm. 4 | func Kmp(word, text string, patternTable []int) []int { 5 | if len(word) > len(text) { 6 | return nil 7 | } 8 | 9 | var ( 10 | i, j int 11 | matches []int 12 | ) 13 | for i+j < len(text) { 14 | 15 | if word[j] == text[i+j] { 16 | j++ 17 | if j == len(word) { 18 | matches = append(matches, i) 19 | 20 | i = i + j 21 | j = 0 22 | } 23 | } else { 24 | i = i + j - patternTable[j] 25 | if patternTable[j] > -1 { 26 | j = patternTable[j] 27 | } else { 28 | j = 0 29 | } 30 | } 31 | } 32 | return matches 33 | } 34 | 35 | // table building for kmp algorithm. 36 | func table(w string) []int { 37 | var ( 38 | t []int = []int{-1} 39 | k int 40 | ) 41 | for j := 1; j < len(w); j++ { 42 | k = j - 1 43 | for w[0:k] != w[j-k:j] && k > 0 { 44 | k-- 45 | } 46 | t = append(t, k) 47 | } 48 | return t 49 | } 50 | -------------------------------------------------------------------------------- /strings/levenshtein/levenshteindistance.go: -------------------------------------------------------------------------------- 1 | /* 2 | This algorithm calculates the distance between two strings. 3 | Parameters: two strings to compare and weights of insertion, substitution and deletion. 4 | Output: distance between both strings 5 | */ 6 | 7 | package levenshtein 8 | 9 | // Distance Function that gives Levenshtein Distance 10 | func Distance(str1, str2 string, icost, scost, dcost int) int { 11 | row1 := make([]int, len(str2)+1) 12 | row2 := make([]int, len(str2)+1) 13 | 14 | for i := 1; i <= len(str2); i++ { 15 | row1[i] = i * icost 16 | } 17 | 18 | for i := 1; i <= len(str1); i++ { 19 | row2[0] = i * dcost 20 | 21 | for j := 1; j <= len(str2); j++ { 22 | if str1[i-1] == str2[j-1] { 23 | row2[j] = row1[j-1] 24 | } else { 25 | ins := row2[j-1] + icost 26 | del := row1[j] + dcost 27 | sub := row1[j-1] + scost 28 | 29 | if ins < del && ins < sub { 30 | row2[j] = ins 31 | } else if del < sub { 32 | row2[j] = del 33 | } else { 34 | row2[j] = sub 35 | } 36 | } 37 | } 38 | row1, row2 = row2, row1 39 | } 40 | 41 | return row1[len(row1)-1] 42 | } 43 | -------------------------------------------------------------------------------- /strings/levenshtein/levenshteindistance_test.go: -------------------------------------------------------------------------------- 1 | package levenshtein 2 | 3 | import "testing" 4 | 5 | var testCases = []struct { 6 | name string 7 | string1 string 8 | string2 string 9 | insertionCost int 10 | substitutionCost int 11 | deletionCost int 12 | expected int 13 | }{ 14 | { 15 | "strings with equal operation weights.", 16 | "stingy", 17 | "ring", 18 | 1, 19 | 1, 20 | 1, 21 | 3, 22 | }, 23 | { 24 | "strings with different operation weights.", 25 | "stingy", 26 | "ring", 27 | 1, 28 | 1, 29 | 3, 30 | 7, 31 | }, 32 | { 33 | "strings with different operation weights.", 34 | "kitten", 35 | "sitting", 36 | 1, 37 | 1, 38 | 1, 39 | 3, 40 | }, 41 | } 42 | 43 | func TestLevenshteinDistance(t *testing.T) { 44 | for _, tc := range testCases { 45 | t.Run(tc.name, func(t *testing.T) { 46 | actual := Distance(tc.string1, tc.string2, tc.insertionCost, tc.substitutionCost, tc.deletionCost) 47 | if actual != tc.expected { 48 | t.Errorf("Expected Levenshtein distance between strings: '%s' and '%s' is %v, but got: %v", tc.string1, tc.string2, tc.expected, actual) 49 | } 50 | }) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /strings/manacher/longestpalindrome_test.go: -------------------------------------------------------------------------------- 1 | // longestpalindrome_test.go 2 | // description: Manacher's algorithm (Longest palindromic substring) 3 | // author(s) [red_byte](https://github.com/i-redbyte) 4 | // see longestpalindrome.go 5 | 6 | package manacher 7 | 8 | import "testing" 9 | 10 | func getTests() []struct { 11 | s string 12 | result string 13 | } { 14 | var tests = []struct { 15 | s string 16 | result string 17 | }{ 18 | {"olokazakabba", "kazak"}, 19 | {"abaacakkkkk", "kkkkk"}, 20 | {"qqqq C++ groovy mom pooop", "pooop"}, 21 | {"CCCPCCC @@@ hello", "CCCPCCC"}, 22 | {"goog gogogogogog -go- gogogogo ", "gogogogogog"}, 23 | } 24 | return tests 25 | } 26 | 27 | func TestLongestPalindrome(t *testing.T) { 28 | tests := getTests() 29 | for _, tv := range tests { 30 | t.Run(tv.s, func(t *testing.T) { 31 | result := LongestPalindrome(tv.s) 32 | t.Log(tv.s, " ", result) 33 | if result != tv.result { 34 | t.Errorf("Wrong result! Expected:%s, returned:%s ", tv.result, result) 35 | } 36 | }) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /strings/pangram/ispangram.go: -------------------------------------------------------------------------------- 1 | // ispangram.go 2 | // description: Checks if a given string is pangram or not 3 | // details: A pangram is a sentence or expression that uses all the letters of the alphabet. 4 | // Reference: https://www.geeksforgeeks.org/pangram-checking/ 5 | // Author : Kavitha J 6 | 7 | package pangram 8 | 9 | import ( 10 | "regexp" 11 | "strings" 12 | ) 13 | 14 | func cleanString(text string) string { 15 | cleanText := strings.ToLower(text) // Convert to lowercase 16 | cleanText = strings.Join(strings.Fields(cleanText), "") // Remove spaces 17 | regex, _ := regexp.Compile(`[^\p{L}\p{N} ]+`) // Regular expression for alphanumeric only characters 18 | return regex.ReplaceAllString(cleanText, "") 19 | } 20 | 21 | func IsPangram(text string) bool { 22 | cleanText := cleanString(text) 23 | if len(cleanText) < 26 { 24 | return false 25 | } 26 | var data = make(map[rune]bool) 27 | for _, i := range cleanText { 28 | data[i] = true 29 | } 30 | return len(data) == 26 31 | } 32 | -------------------------------------------------------------------------------- /strings/pangram/ispangram_test.go: -------------------------------------------------------------------------------- 1 | package pangram 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var testCases = []struct { 8 | name string // test description 9 | input string // user input 10 | expected bool // expected return 11 | }{ 12 | { 13 | "empty string", 14 | "", 15 | false, 16 | }, 17 | { 18 | "non pangram string without spaces", 19 | "abc", 20 | false, 21 | }, 22 | { 23 | "non pangram string with spaces", 24 | "Hello World", 25 | false, 26 | }, 27 | { 28 | "Pangram string 1", 29 | " Abcdefghijklmnopqrstuvwxyz", 30 | true, 31 | }, 32 | { 33 | "pangram string 2", 34 | "cdefghijklmnopqrstuvwxABC zyb", 35 | true, 36 | }, 37 | { 38 | "pangram string 3", 39 | "The Quick Brown Fox Jumps Over the Lazy Dog", 40 | true, 41 | }, 42 | } 43 | 44 | func TestIsPangram(t *testing.T) { 45 | for _, test := range testCases { 46 | t.Run(test.name, func(t *testing.T) { 47 | func_result := IsPangram(test.input) 48 | if test.expected != func_result { 49 | t.Errorf("Expected answer '%t' for string '%s' but answer given was %t", test.expected, test.input, func_result) 50 | } 51 | }) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /strings/parenthesis/parenthesis.go: -------------------------------------------------------------------------------- 1 | package parenthesis 2 | 3 | // Parenthesis algorithm checks if every opened parenthesis 4 | // is closed correctly. When parcounter is less than 0 when a closing 5 | // parenthesis is detected without an opening parenthesis 6 | // that surrounds it and parcounter will be 0 if all open 7 | // parenthesis are closed correctly. 8 | func Parenthesis(text string) bool { 9 | parcounter := 0 10 | 11 | for _, r := range text { 12 | switch r { 13 | case '(': 14 | parcounter++ 15 | case ')': 16 | parcounter-- 17 | } 18 | if parcounter < 0 { 19 | return false 20 | } 21 | } 22 | return parcounter == 0 23 | } 24 | -------------------------------------------------------------------------------- /strings/parenthesis/parenthesis_test.go: -------------------------------------------------------------------------------- 1 | package parenthesis 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var parenthesisTestCases = []struct { 8 | name string 9 | text string 10 | expected bool 11 | }{ 12 | { 13 | "simple test with one level deep", 14 | "(3*9-2)+(3/7^3)", 15 | true, 16 | }, 17 | { 18 | "three nested parenthesis with three deep level", 19 | "(-1*(5+2^(3-4)*(7.44-12)+6.66/(3.43-(1+2)))*(sqrt(3-4)))", 20 | true, 21 | }, 22 | { 23 | "one opened parenthesis without be closed", 24 | "(2*9-17)*((7+3/3)*2*(-1+4)", 25 | false, 26 | }, 27 | { 28 | "one open parenthesis for each close one but not in pairs", 29 | "(4*(39.22-7.4)/6.77))(", 30 | false, 31 | }, 32 | { 33 | "6 deep level", 34 | "(5+33.2)*((8.04-6.5)*(1 - (1^(2-1.22*5.44+(4.33*7.2^(0.34*(-1.23+2)))))))", 35 | true, 36 | }, 37 | { 38 | "inverted parenthesis", 39 | ")()()()()(", 40 | false, 41 | }, 42 | } 43 | 44 | func TestParenthesis(t *testing.T) { 45 | for _, tc := range parenthesisTestCases { 46 | t.Run(tc.name, func(t *testing.T) { 47 | actual := Parenthesis(tc.text) 48 | if actual != tc.expected { 49 | t.Errorf("Expected %t value from test %s with input %s\n", tc.expected, tc.name, tc.text) 50 | } 51 | }) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /strings/search/naive.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | // Implementation of naive string search 4 | // O(n*m) where n=len(txt) and m=len(pattern) 5 | func Naive(text string, pattern string) []int { 6 | var positions []int 7 | for i := 0; i <= len(text)-len(pattern); i++ { 8 | var match bool = true 9 | for j := 0; j < len(pattern); j++ { 10 | if text[i+j] != pattern[j] { 11 | match = false 12 | break 13 | } 14 | 15 | } 16 | if match { 17 | positions = append(positions, i) 18 | } 19 | } 20 | return positions 21 | } 22 | -------------------------------------------------------------------------------- /strings/strings_test.go: -------------------------------------------------------------------------------- 1 | // Empty test file to keep track of all the tests for the algorithms. 2 | 3 | package strings 4 | -------------------------------------------------------------------------------- /structure/doc.go: -------------------------------------------------------------------------------- 1 | // Package structure is a subpackage that is dedicated to 2 | // different implementations of data structures in the 3 | // domain of computer science. 4 | package structure 5 | -------------------------------------------------------------------------------- /structure/linkedlist/Linked_Cyclic_List.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheAlgorithms/Go/5ba447ec5ff3d1213de65b92e726ee74c5d5cc19/structure/linkedlist/Linked_Cyclic_List.jpg -------------------------------------------------------------------------------- /structure/linkedlist/doc.go: -------------------------------------------------------------------------------- 1 | // Package linkedlist demonstrates different implementations on linkedlists. 2 | package linkedlist 3 | -------------------------------------------------------------------------------- /structure/linkedlist/shared.go: -------------------------------------------------------------------------------- 1 | package linkedlist 2 | 3 | // Node Structure representing the linkedlist node. 4 | // This node is shared across different implementations. 5 | type Node[T any] struct { 6 | Val T 7 | Prev *Node[T] 8 | Next *Node[T] 9 | } 10 | 11 | // Create new node. 12 | func NewNode[T any](val T) *Node[T] { 13 | return &Node[T]{val, nil, nil} 14 | } 15 | -------------------------------------------------------------------------------- /structure/set/setexample_test.go: -------------------------------------------------------------------------------- 1 | package set 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func ExampleSet() { 8 | 9 | set := New(1, 2, 3) 10 | fmt.Println(set.Len()) // 3 11 | set.Add(3) 12 | fmt.Println(set.Len()) // 3 13 | set.Add(4) 14 | fmt.Println(set.Len()) // 4 15 | 16 | // output: 17 | // 3 18 | // 3 19 | // 4 20 | } 21 | -------------------------------------------------------------------------------- /structure/structure_test.go: -------------------------------------------------------------------------------- 1 | // Empty test file to keep track of all the tests for the algorithms. 2 | 3 | package structure 4 | -------------------------------------------------------------------------------- /structure/trie/trieexample_test.go: -------------------------------------------------------------------------------- 1 | package trie 2 | 3 | import "fmt" 4 | 5 | func ExampleNode() { 6 | // creates a new node 7 | node := NewNode() 8 | 9 | // adds words 10 | node.Insert("nikola") 11 | node.Insert("tesla") 12 | 13 | // check size and capacity 14 | fmt.Println(node.Size()) // 2 words 15 | fmt.Println(node.Capacity()) // 12 nodes 16 | 17 | // finds words 18 | fmt.Println(node.Find("thomas")) // false 19 | fmt.Println(node.Find("edison")) // false 20 | fmt.Println(node.Find("nikola")) // true 21 | 22 | // remove a word, and check it is gone 23 | node.Remove("tesla") 24 | fmt.Println(node.Find("tesla")) // false 25 | 26 | // size and capacity have changed 27 | fmt.Println(node.Size()) // 1 word left 28 | fmt.Println(node.Capacity()) // 12 nodes remaining 29 | 30 | // output: 31 | // 2 32 | // 12 33 | // false 34 | // false 35 | // true 36 | // false 37 | // 1 38 | // 12 39 | } 40 | --------------------------------------------------------------------------------