diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..e6ced89f --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,18 @@ +# Welcome to Dart community + +### **Describe your change:** + +* [ ] Add an algorithm? +* [ ] Fix a bug or typo in an existing algorithm? +* [ ] Documentation change? +* [ ] Add/Update/Fix test cases. + + +### **Checklist:** +* [ ] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Dart/blob/master/CONTRIBUTING.md). +* [ ] This pull request is all my own work -- I have not plagiarized. +* [ ] I know that pull requests will not be merged if they fail the automated tests. +* [ ] This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms. +* [ ] All new Dart files are placed inside an existing directory. +* [ ] All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation. +* [ ] If this pull request resolves one or more open issues then the commit message contains `Fixes: #{$ISSUE_NO}`. diff --git a/.github/workflows/dart_test_analyze_format.yml b/.github/workflows/dart_test_analyze_format.yml new file mode 100644 index 00000000..a0911f2e --- /dev/null +++ b/.github/workflows/dart_test_analyze_format.yml @@ -0,0 +1,15 @@ +name: dart_test_analyze_format +on: [push, pull_request] +jobs: + dart_test_analyze_format: + runs-on: ubuntu-latest + container: + image: dart:stable + steps: + - uses: actions/checkout@v4 + # - run: (echo 'deb http://deb.debian.org/debian buster main contrib non-free') > /etc/apt/sources.list.d/buster.list + - run: dart pub get + - run: dart format --set-exit-if-changed . + - run: dart test --coverage . + - run: dart run coverage:format_coverage -i . -l > coverage.lcov + - run: dart analyze diff --git a/.github/workflows/update_directory_md.yml b/.github/workflows/update_directory_md.yml index 730d4e13..32dcf94d 100644 --- a/.github/workflows/update_directory_md.yml +++ b/.github/workflows/update_directory_md.yml @@ -4,8 +4,8 @@ jobs: update_directory_md: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions/setup-python@master + - uses: actions/checkout@v1 # v1, NOT v2 + - uses: actions/setup-python@v2 - name: update_directory_md shell: python run: | diff --git a/.gitignore b/.gitignore index dbef116d..d66e1b9e 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ doc/api/ *.js_ *.js.deps *.js.map +*.json diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8d3f8098..00000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: dart -dart: -# Install the latest stable release -- stable -# Install the latest dev release -- dev -# Install a specific stable release - 1.15.0 -- "1.15.0" -# Install a specific dev release, using a partial download URL - 2.9.0-2.0.dev -- "dev/release/2.9.0-2.0.dev" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe634161..fe26c3e3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,17 +3,21 @@ Welcome to [TheAlgorithms/Dart](https://github.com/TheAlgorithms/Dart)! ## Contributing -* Fork this [repo](https://github.com/TheAlgorithms/Dart) +* Fork this [repo](https://github.com/TheAlgorithms/Dart). +* If Already Forked, Then make sure to sync your fork. * Make some changes and pull a request -* Your algorithm must be able to run on [dartpad](https://dartpad.dev/) +* [Automated tests are run](https://github.com/TheAlgorithms/Dart/actions) on all pull requests + * `dart analyze` is mandatory + * `dart format` is mandatory + * `dart test` is recommended ## New File Name guidelines * Use lowercase words with "_" as separator -* For example +* For example: ``` MyNewAlgorithm.dart is incorrect -my_new_algorithm.dart is correct format -My_New_Algorithm.dart is correct format +my_new_algorithm.dart is correct format ``` Writer [@StepfenShawn](https://github.com/StepfenShawn), Feb 2020. +Updated [@akashgk](https://github.com/akashgk), Oct 2022. diff --git a/DIRECTORY.md b/DIRECTORY.md index 61f81363..48986dc4 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -1,60 +1,159 @@ +## Array + * [Car Pool](https://github.com/TheAlgorithms/Dart/blob/master/array/car_pool.dart) + * [Move Zeroes](https://github.com/TheAlgorithms/Dart/blob/master/array/move_zeroes.dart) + * [Pivot Index](https://github.com/TheAlgorithms/Dart/blob/master/array/pivot_index.dart) + * [Sorted Squared Array](https://github.com/TheAlgorithms/Dart/blob/master/array/sorted_squared_array.dart) + * [Two Sum](https://github.com/TheAlgorithms/Dart/blob/master/array/two_sum.dart) + * [Validate Subsequence](https://github.com/TheAlgorithms/Dart/blob/master/array/validate_subsequence.dart) + +## Backtracking + * [N-Queen](https://github.com/TheAlgorithms/Dart/blob/master/backtracking/n-queen.dart) + * [Open Knight Tour](https://github.com/TheAlgorithms/Dart/blob/master/backtracking/open_knight_tour.dart) + ## Conversions + * [Binary To Decimal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/binary_to_decimal.dart) + * [Binary To Hexadecimal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/binary_to_hexadecimal.dart) + * [Binary To Octal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/binary_to_octal.dart) + * [Decimal To Any](https://github.com/TheAlgorithms/Dart/blob/master/conversions/Decimal_To_Any.dart) * [Decimal To Binary](https://github.com/TheAlgorithms/Dart/blob/master/conversions/Decimal_To_Binary.dart) + * [Decimal To Hexadecimal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/Decimal_to_Hexadecimal.dart) + * [Decimal To Octal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/Decimal_to_Octal.dart) + * [Hexadecimal To Binary](https://github.com/TheAlgorithms/Dart/blob/master/conversions/hexadecimal_to_binary.dart) + * [Hexadecimal To Decimal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/hexadecimal_to_decimal.dart) + * [Hexadecimal To Octal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/hexadecimal_to_octal.dart) + * [Integer To Roman](https://github.com/TheAlgorithms/Dart/blob/master/conversions/Integer_To_Roman.dart) + * [Octal To Binary](https://github.com/TheAlgorithms/Dart/blob/master/conversions/octal_to_binary.dart) + * [Octal To Decimal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/octal_to_decimal.dart) + * [Octal To Hexadecimal](https://github.com/TheAlgorithms/Dart/blob/master/conversions/octal_to_hexadecimal.dart) + * [Roman To Integer](https://github.com/TheAlgorithms/Dart/blob/master/conversions/roman_to_integer.dart) ## Data Structures * Binary Tree * [Basic Binary Tree](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/binary_tree/basic_binary_tree.dart) + * [Binary Tree Traversal](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/binary_tree/binary_tree_traversal.dart) * Hashmap * [Hashing](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/HashMap/Hashing.dart) * Heap * Binary Heap + * [Max Heap](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Heap/Binary_Heap/Max_heap.dart) * [Min Heap](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Heap/Binary_Heap/Min_Heap.dart) - * [Linked List](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/linked_list.dart) + * [Min Heap Two](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Heap/Binary_Heap/min_heap_two.dart) + * Linked List + * [Cycle In Linked List](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/linked_list/cycle_in_linked_list.dart) + * [Linked List](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/linked_list/linked_list.dart) + * [Merge Sorted List](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/linked_list/merge_sorted_list.dart) * Queue + * [Circular Queue](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Queue/Circular_Queue.dart) * [List Queue](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Queue/List_Queue.dart) + * [Priority Queue](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Queue/Priority_Queue.dart) * Stack * [Array Stack](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Stack/Array_Stack.dart) + * [Balanced Brackets](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Stack/balanced_brackets.dart) * [Linked List Stack](https://github.com/TheAlgorithms/Dart/blob/master/data_structures/Stack/Linked_List_Stack.dart) +## Dynamic Programming + * [01Knapsack Recursive](https://github.com/TheAlgorithms/Dart/blob/master/dynamic_programming/01knapsack_recursive.dart) + * [Coin Change](https://github.com/TheAlgorithms/Dart/blob/master/dynamic_programming/coin_change.dart) + * [Kadanes Algorithm](https://github.com/TheAlgorithms/Dart/blob/master/dynamic_programming/kadanes_algorithm.dart) + * [Longest Common Subsequence](https://github.com/TheAlgorithms/Dart/blob/master/dynamic_programming/longest_common_subsequence.dart) + * [Longest Common Substring](https://github.com/TheAlgorithms/Dart/blob/master/dynamic_programming/longest_common_substring.dart) + * [Min Number Of Jumps](https://github.com/TheAlgorithms/Dart/blob/master/dynamic_programming/min_number_of_jumps.dart) + ## Graphs + * [Area Of Island](https://github.com/TheAlgorithms/Dart/blob/master/graphs/area_of_island.dart) + * [Breadth First Search](https://github.com/TheAlgorithms/Dart/blob/master/graphs/breadth_first_search.dart) + * [Depth First Search](https://github.com/TheAlgorithms/Dart/blob/master/graphs/depth_first_search.dart) * [Nearest Neighbour Algorithm](https://github.com/TheAlgorithms/Dart/blob/master/graphs/nearest_neighbour_algorithm.dart) ## Maths * [Abs](https://github.com/TheAlgorithms/Dart/blob/master/maths/abs.dart) * [Abs Max](https://github.com/TheAlgorithms/Dart/blob/master/maths/abs_max.dart) * [Abs Min](https://github.com/TheAlgorithms/Dart/blob/master/maths/abs_min.dart) + * [Amicable Numbers](https://github.com/TheAlgorithms/Dart/blob/master/maths/amicable_numbers.dart) + * [Armstrong Number](https://github.com/TheAlgorithms/Dart/blob/master/maths/Armstrong_number.dart) * [Average](https://github.com/TheAlgorithms/Dart/blob/master/maths/average.dart) + * [Eulers Totient](https://github.com/TheAlgorithms/Dart/blob/master/maths/eulers_totient.dart) * [Factorial](https://github.com/TheAlgorithms/Dart/blob/master/maths/factorial.dart) * [Factorial Approximation](https://github.com/TheAlgorithms/Dart/blob/master/maths/factorial_approximation.dart) * [Factorial Recursion](https://github.com/TheAlgorithms/Dart/blob/master/maths/factorial_recursion.dart) + * [Factors](https://github.com/TheAlgorithms/Dart/blob/master/maths/factors.dart) * [Fermats Little Theorem](https://github.com/TheAlgorithms/Dart/blob/master/maths/fermats_little_theorem.dart) + * [Fibonacci Dynamic Programming](https://github.com/TheAlgorithms/Dart/blob/master/maths/fibonacci_dynamic_programming.dart) * [Fibonacci Recursion](https://github.com/TheAlgorithms/Dart/blob/master/maths/fibonacci_recursion.dart) * [Find Max](https://github.com/TheAlgorithms/Dart/blob/master/maths/find_max.dart) * [Find Max Recursion](https://github.com/TheAlgorithms/Dart/blob/master/maths/find_max_recursion.dart) * [Find Min](https://github.com/TheAlgorithms/Dart/blob/master/maths/find_min.dart) * [Find Min Recursion](https://github.com/TheAlgorithms/Dart/blob/master/maths/find_min_recursion.dart) * [Hamming Distance](https://github.com/TheAlgorithms/Dart/blob/master/maths/hamming_distance.dart) + * [Kynea Numbers](https://github.com/TheAlgorithms/Dart/blob/master/maths/Kynea_numbers.dart) + * [Lineardiophantineeqn](https://github.com/TheAlgorithms/Dart/blob/master/maths/LinearDiophantineEqn.dart) * [Lu Decomposition](https://github.com/TheAlgorithms/Dart/blob/master/maths/lu_decomposition.dart) * [Newton Method](https://github.com/TheAlgorithms/Dart/blob/master/maths/newton_method.dart) * [Palindrome Number](https://github.com/TheAlgorithms/Dart/blob/master/maths/palindrome_number.dart) * [Palindrome String](https://github.com/TheAlgorithms/Dart/blob/master/maths/palindrome_string.dart) * [Palindrome String Recursion](https://github.com/TheAlgorithms/Dart/blob/master/maths/palindrome_string_recursion.dart) - * [Pow](https://github.com/TheAlgorithms/Dart/blob/master/maths/Pow.dart) + * [Perfect Number](https://github.com/TheAlgorithms/Dart/blob/master/maths/perfect_number.dart) + * [Pow](https://github.com/TheAlgorithms/Dart/blob/master/maths/pow.dart) + * [Power Of Two](https://github.com/TheAlgorithms/Dart/blob/master/maths/power_of_two.dart) * [Prime Check](https://github.com/TheAlgorithms/Dart/blob/master/maths/prime_check.dart) + * [Relu Function](https://github.com/TheAlgorithms/Dart/blob/master/maths/relu_function.dart) + * [Shreedharacharya](https://github.com/TheAlgorithms/Dart/blob/master/maths/shreedharacharya.dart) + * [Sieve Of Eratosthenes](https://github.com/TheAlgorithms/Dart/blob/master/maths/sieve_of_eratosthenes.dart) + * [Sigmoid](https://github.com/TheAlgorithms/Dart/blob/master/maths/sigmoid.dart) * [Simpson Rule](https://github.com/TheAlgorithms/Dart/blob/master/maths/simpson_rule.dart) + * [Sphenic Number](https://github.com/TheAlgorithms/Dart/blob/master/maths/sphenic_number.dart) * [Symmetric Derivative](https://github.com/TheAlgorithms/Dart/blob/master/maths/symmetric_derivative.dart) + * [Ugly Numbers](https://github.com/TheAlgorithms/Dart/blob/master/maths/Ugly_numbers.dart) ## Other * [Ackermann](https://github.com/TheAlgorithms/Dart/blob/master/other/ackermann.dart) + * [Binpow](https://github.com/TheAlgorithms/Dart/blob/master/other/binpow.dart) + * [Chinese Remainder Theorem](https://github.com/TheAlgorithms/Dart/blob/master/other/chinese_remainder_theorem.dart) * [Collatz](https://github.com/TheAlgorithms/Dart/blob/master/other/collatz.dart) * [Fisher Yates Shuffle](https://github.com/TheAlgorithms/Dart/blob/master/other/fisher_yates_shuffle.dart) + * [Fizzbuzz](https://github.com/TheAlgorithms/Dart/blob/master/other/FizzBuzz.dart) * [Gcd](https://github.com/TheAlgorithms/Dart/blob/master/other/gcd.dart) * [Haversine Formula](https://github.com/TheAlgorithms/Dart/blob/master/other/haversine_formula.dart) * [Heaps Algorithm](https://github.com/TheAlgorithms/Dart/blob/master/other/heaps_algorithm.dart) + * [Kadanealgo](https://github.com/TheAlgorithms/Dart/blob/master/other/kadaneAlgo.dart) * [Lcm](https://github.com/TheAlgorithms/Dart/blob/master/other/LCM.dart) + * [Magic Number](https://github.com/TheAlgorithms/Dart/blob/master/other/magic_number.dart) + * [Moore Voting Algorithm](https://github.com/TheAlgorithms/Dart/blob/master/other/Moore_voting_algorithm.dart) + * [N Bonacci](https://github.com/TheAlgorithms/Dart/blob/master/other/N_bonacci.dart) + * [Swap All Odd And Even Bits](https://github.com/TheAlgorithms/Dart/blob/master/other/swap_all_odd_and_even_bits.dart) * [Tower Of Hanoi](https://github.com/TheAlgorithms/Dart/blob/master/other/tower_of_hanoi.dart) +## Project Euler + * Problem 1 + * [Sol1](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_1/sol1.dart) + * Problem 10 + * [Sol10](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_10/sol10.dart) + * Problem 12 + * [Sol12](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_12/sol12.dart) + * Problem 13 + * [Sol13](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_13/sol13.dart) + * Problem 17 + * [Sol17](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_17/sol17.dart) + * Problem 2 + * [Sol2](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_2/sol2.dart) + * Problem 20 + * [Sol20](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_20/sol20.dart) + * Problem 3 + * [Sol3](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_3/sol3.dart) + * Problem 4 + * [Sol4](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_4/sol4.dart) + * Problem 5 + * [Sol5](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_5/sol5.dart) + * Problem 6 + * [Sol6](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_6/sol6.dart) + * Problem 7 + * [Sol7](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_7/sol7.dart) + * Problem 8 + * [Sol8](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_8/sol8.dart) + * Problem 9 + * [Sol9](https://github.com/TheAlgorithms/Dart/blob/master/project_euler/problem_9/sol9.dart) + ## Search * [Binary Search](https://github.com/TheAlgorithms/Dart/blob/master/search/binary_Search.dart) * [Binary Search Recursion](https://github.com/TheAlgorithms/Dart/blob/master/search/binary_search_recursion.dart) @@ -62,14 +161,31 @@ * [Interpolation Search](https://github.com/TheAlgorithms/Dart/blob/master/search/interpolation_Search.dart) * [Jump Search](https://github.com/TheAlgorithms/Dart/blob/master/search/jump_Search.dart) * [Linear Search](https://github.com/TheAlgorithms/Dart/blob/master/search/linear_Search.dart) + * [Peak Element](https://github.com/TheAlgorithms/Dart/blob/master/search/peak_element.dart) * [Ternary Search](https://github.com/TheAlgorithms/Dart/blob/master/search/ternary_Search.dart) ## Sort * [Bubble Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/bubble_Sort.dart) + * [Cocktail Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/cocktail_sort.dart) + * [Comb Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/comb_sort.dart) + * [Count Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/count_sort.dart) * [Gnome Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/gnome_Sort.dart) * [Heap Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/heap_Sort.dart) * [Insert Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/insert_Sort.dart) + * [Merge Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/merge_sort.dart) + * [Pigeonhole Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/pigeonhole_sort.dart) * [Quick Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/quick_Sort.dart) + * [Radix Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/radix_sort.dart) * [Select Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/select_Sort.dart) * [Shell Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/shell_Sort.dart) * [Tim Sort](https://github.com/TheAlgorithms/Dart/blob/master/sort/tim_Sort.dart) + +## Strings + * [Isomorphic Strings](https://github.com/TheAlgorithms/Dart/blob/master/strings/isomorphic_strings.dart) + * [Knuth Morris Prat](https://github.com/TheAlgorithms/Dart/blob/master/strings/knuth_morris_prat.dart) + * [Remove Duplicates](https://github.com/TheAlgorithms/Dart/blob/master/strings/remove%20duplicates.dart) + * [Reverse String](https://github.com/TheAlgorithms/Dart/blob/master/strings/reverse_string.dart) + * [Reverse Words Of String](https://github.com/TheAlgorithms/Dart/blob/master/strings/reverse_words_of_string.dart) + +## Trees + * [Path Sum](https://github.com/TheAlgorithms/Dart/blob/master/trees/path_sum.dart) diff --git a/LICENSE b/LICENSE index 3b795152..76ef0691 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 The Algorithms +Copyright (c) 2026 The Algorithms Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 550ccdda..309e9c8d 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,165 @@ -# The Algorithms - Dart +# The Algorithms - Dart +[![Build Status](https://travis-ci.com/TheAlgorithms/Dart.svg?branch=master)](https://travis-ci.com/TheAlgorithms/Dart) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/TheAlgorithms/100)   -[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/TheAlgorithms)   +[![Discord chat](https://img.shields.io/discord/808045925556682782.svg?logo=discord&colorB=5865F2)](https://the-algorithms.com/discord/)   +[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/#TheAlgorithms_community:gitter.im) ### All algorithms implemented in Dart (for education) These implementations are for learning purposes. They may be less efficient than the implementations in the Dart standard library. -## Owners/Maintainer +## List of Algorithms -Anup Kumar Panwar -  [[Gmail](mailto:1anuppanwar@gmail.com?Subject=The%20Algorithms%20-%20Python) -  [GitHub](https://github.com/anupkumarpanwar) -  [LinkedIn](https://www.linkedin.com/in/anupkumarpanwar/)] +See our [directory](https://github.com/TheAlgorithms/Dart/blob/master/DIRECTORY.md) for full list of all algorithms. A few of the algorithms (the most common ones) are explained here. -Chetan Kaushik -  [[Gmail](mailto:dynamitechetan@gmail.com?Subject=The%20Algorithms%20-%20Python) -  [GitHub](https://github.com/dynamitechetan) -  [LinkedIn](https://www.linkedin.com/in/chetankaushik/)] +## Search Algorithms -Shawn -  [[GitHub](https://github.com/StepfenShawn)] +### Linear +![alt text][linear-image] -## List of Algorithms +From [Wikipedia][linear-wiki]: linear search or sequential search is a method for finding a target value within a list. It sequentially checks each element of the list for the target value until a match is found or until all the elements have been searched. + Linear search runs in at the worst linear time and makes at most n comparisons, where n is the length of the list. + +__Properties__ +* Worst case performance O(n) +* Best case performance O(1) +* Average case performance O(n) +* Worst case space complexity O(1) iterative + + +### Binary +![alt text][binary-image] + +From [Wikipedia][binary-wiki]: Binary search, also known as half-interval search or logarithmic search, is a search algorithm that finds the position of a target value within a sorted array. It compares the target value to the middle element of the array; if they are unequal, the half in which the target cannot lie is eliminated and the search continues on the remaining half until it is successful. + +__Properties__ +* Worst case performance O(log n) +* Best case performance O(1) +* Average case performance O(log n) +* Worst case space complexity O(1) + +---------------------------------------------------------------------------------------------------------------------- + +## Sort Algorithms + + +### Bubble +![alt text][bubble-image] + +From [Wikipedia][bubble-wiki]: Bubble sort, sometimes referred to as sinking sort, is a simple sorting algorithm that repeatedly steps through the list to be sorted, compares each pair of adjacent items and swaps them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. + +__Properties__ +* Worst case performance O(n^2) +* Best case performance O(n) +* Average case performance O(n^2) + +###### View the algorithm in [action][bubble-toptal] + + + +### Insertion +![alt text][insertion-image] + +From [Wikipedia][insertion-wiki]: Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. + +__Properties__ +* Worst case performance O(n^2) +* Best case performance O(n) +* Average case performance O(n^2) + +###### View the algorithm in [action][insertion-toptal] + + +### Quick +![alt text][quick-image] + +From [Wikipedia][quick-wiki]: Quicksort (sometimes called partition-exchange sort) is an efficient sorting algorithm, serving as a systematic method for placing the elements of an array in order. + +__Properties__ +* Worst case performance O(n^2) +* Best case performance O(n log n) or O(n) with three-way partition +* Average case performance O(n^2) + +###### View the algorithm in [action][quick-toptal] + +### Selection +![alt text][selection-image] + +From [Wikipedia][selection-wiki]: The algorithm divides the input list into two parts: the sublist of items already sorted, which is built up from left to right at the front (left) of the list, and the sublist of items remaining to be sorted that occupy the rest of the list. Initially, the sorted sublist is empty and the unsorted sublist is the entire input list. The algorithm proceeds by finding the smallest (or largest, depending on sorting order) element in the unsorted sublist, exchanging (swapping) it with the leftmost unsorted element (putting it in sorted order), and moving the sublist boundaries one element to the right. + +__Properties__ +* Worst case performance O(n^2) +* Best case performance O(n^2) +* Average case performance O(n^2) + +###### View the algorithm in [action][selection-toptal] + + +### Merge +![alt text][merge-image] + +From [Wikipedia][merge-wiki]: Merge sort (also commonly spelled mergesort) is a divide and conquer algorithm that was invented by John von Neumann in 1945. The algorithm dirst divides the list into the smallest unit (1 element), then compares each element with the adjacent list to sort and merge the two adjacent lists. Finally all the elements are sorted and merged. It is an efficient, general-purpose, comparison-based sorting algorithm. + +__Properties__ +* Worst case performance O(n log n) +* Best case performance O(n log n) +* Average case performance O(n log n) + +###### View the algorithm in [action][merge-toptal] + + +### Shell +![alt text][shell-image] + +From [Wikipedia][shell-wiki]: Shellsort is a generalization of insertion sort that allows the exchange of items that are far apart. The idea is to arrange the list of elements so that, starting anywhere, considering every nth element gives a sorted list. Such a list is said to be h-sorted. Equivalently, it can be thought of as h interleaved lists, each individually sorted. + +__Properties__ +* Worst case performance O(nlog2 2n) +* Best case performance O(n log n) +* Average case performance depends on gap sequence + +###### View the algorithm in [action][shell-toptal] + +### Time-Complexity Graphs + +Comparing the complexity of sorting algorithms (Bubble Sort, Selection Sort and Insertion Sort) + +![alt text][complexity-graph] + +[bubble-toptal]: https://www.toptal.com/developers/sorting-algorithms/bubble-sort +[bubble-wiki]: https://en.wikipedia.org/wiki/Bubble_sort +[bubble-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Bubblesort-edited-color.svg/220px-Bubblesort-edited-color.svg.png "Bubble Sort" + +[insertion-toptal]: https://www.toptal.com/developers/sorting-algorithms/insertion-sort +[insertion-wiki]: https://en.wikipedia.org/wiki/Insertion_sort +[insertion-image]: https://upload.wikimedia.org/wikipedia/commons/7/7e/Insertionsort-edited.png "Insertion Sort" + +[quick-toptal]: https://www.toptal.com/developers/sorting-algorithms/quick-sort +[quick-wiki]: https://en.wikipedia.org/wiki/Quicksort +[quick-image]: https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif "Quick Sort" + +[merge-toptal]: https://www.toptal.com/developers/sorting-algorithms/merge-sort +[merge-wiki]: https://en.wikipedia.org/wiki/Merge_sort +[merge-image]: https://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif "Merge Sort" + +[selection-toptal]: https://www.toptal.com/developers/sorting-algorithms/selection-sort +[selection-wiki]: https://en.wikipedia.org/wiki/Selection_sort +[selection-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Selection_sort_animation.gif/250px-Selection_sort_animation.gif "Selection Sort Sort" + +[shell-toptal]: https://www.toptal.com/developers/sorting-algorithms/shell-sort +[shell-wiki]: https://en.wikipedia.org/wiki/Shellsort +[shell-image]: https://upload.wikimedia.org/wikipedia/commons/d/d8/Sorting_shellsort_anim.gif "Shell Sort" + +[linear-wiki]: https://en.wikipedia.org/wiki/Linear_search +[linear-image]: http://www.tutorialspoint.com/data_structures_algorithms/images/linear_search.gif + +[binary-wiki]: https://en.wikipedia.org/wiki/Binary_search_algorithm +[binary-image]: https://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_search_into_array.png + +[complexity-graph]: https://github.com/prateekiiest/Python/blob/master/sorts/sortinggraphs.png -See our [directory](https://github.com/TheAlgorithms/Dart/blob/master/DIRECTORY.md) +---------------------------------------------------------------------------------- ## Community Channel diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 00000000..00cb9e66 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,3 @@ +analyzer: + exclude: + - maths/fermats_little_theorem.dart diff --git a/array/car_pool.dart b/array/car_pool.dart new file mode 100644 index 00000000..b5cbb401 --- /dev/null +++ b/array/car_pool.dart @@ -0,0 +1,61 @@ +// Leetcode problem: https://leetcode.com/problems/car-pooling/ +// Solution Explanation: https://leetcode.com/problems/car-pooling/solutions/3252690/dart-time-o-n-o-1-space-solution/ + +import 'dart:math'; +import "package:test/test.dart"; + +bool carPooling(List> trips, int capacity) { + List passengerTimelineCount = List.filled(1001, 0); + int lastPoint = 0; + + for (List trip in trips) { + int count = trip[0]; + int from = trip[1]; + int to = trip[2]; + if (count > capacity) { + return false; + } + + lastPoint = max(lastPoint, to); + passengerTimelineCount[from] += count; + passengerTimelineCount[to] -= count; + } + + for (int i = 1; i < lastPoint; ++i) { + passengerTimelineCount[i] += passengerTimelineCount[i - 1]; + if (passengerTimelineCount[i] > capacity) { + return false; + } + } + return true; +} + +void main() { + List> trips = [ + [2, 1, 5], + [3, 3, 7], + ]; + + List> trips1 = [ + [2, 1, 5], + [3, 5, 7], + ]; + + List> trips2 = [ + [2, 2, 6], + [2, 4, 7], + [8, 6, 7], + ]; + + List> trips3 = [ + [7, 5, 6], + [6, 7, 8], + [10, 1, 6], + ]; + + test('test case 1', () => expect(carPooling(trips, 4), false)); + test('test case 2', () => expect(carPooling(trips, 5), true)); + test('test case 3', () => expect(carPooling(trips1, 3), true)); + test('test case 4', () => expect(carPooling(trips2, 11), true)); + test('test case 5', () => expect(carPooling(trips3, 16), false)); +} diff --git a/array/move_zeroes.dart b/array/move_zeroes.dart new file mode 100644 index 00000000..c09aa79c --- /dev/null +++ b/array/move_zeroes.dart @@ -0,0 +1,32 @@ +import 'package:test/test.dart'; + +List moveZeroes(List nums) { + int lastNonZeroFoundAt = 0; + + for (int i = 0; i < nums.length; ++i) { + if (nums[i] != 0) { + nums[lastNonZeroFoundAt] = nums[i]; + lastNonZeroFoundAt += 1; + } + } + + for (int i = lastNonZeroFoundAt; i < nums.length; ++i) { + nums[i] = 0; + } + return nums; +} + +void main() { + test('test case 1', () { + return expect(moveZeroes([1, 0, 2, 0, 0]), [1, 2, 0, 0, 0]); + }); + test('test case 2', () { + return expect(moveZeroes([1, 2, 2, 3, 5]), [1, 2, 2, 3, 5]); + }); + test('test case 3', () { + return expect(moveZeroes([0, 0, 0, 0, 0]), [0, 0, 0, 0, 0]); + }); + test('test case 4', () { + return expect(moveZeroes([]), []); + }); +} diff --git a/array/pivot_index.dart b/array/pivot_index.dart new file mode 100644 index 00000000..b73e74ef --- /dev/null +++ b/array/pivot_index.dart @@ -0,0 +1,30 @@ +import 'package:test/test.dart'; + +// Leetcode problem URL: https://leetcode.com/problems/find-pivot-index/ +int sum(List numbers) { + int sum = 0; + for (int i = 0; i < numbers.length; i++) { + sum += numbers[i]; + } + return sum; +} + +int pivotIndex(List nums) { + int leftSum = 0; + int arraySum = sum(nums); + + for (int i = 0; i < nums.length; ++i) { + if (leftSum == arraySum - leftSum - nums[i]) { + return i; + } + leftSum += nums[i]; + } + + return -1; +} + +void main() { + test('test case 1', () => expect(pivotIndex([1, 7, 3, 6, 5, 6]), 3)); + test('test case 2', () => expect(pivotIndex([2, 1, -1]), 0)); + test('test case 3', () => expect(pivotIndex([1, 2, 3]), -1)); +} diff --git a/array/sorted_squared_array.dart b/array/sorted_squared_array.dart new file mode 100644 index 00000000..791474fc --- /dev/null +++ b/array/sorted_squared_array.dart @@ -0,0 +1,55 @@ +import 'package:test/test.dart'; + +List sortedSquaredArray(List array) { + int start = 0; + int end = array.length - 1; + int sortedIndex = array.length - 1; + List answer = List.filled(array.length, 0); + + while (end >= start) { + if (array[start].abs() > array[end].abs()) { + answer[sortedIndex] = array[start] * array[start]; + start += 1; + } else { + answer[sortedIndex] = array[end] * array[end]; + end -= 1; + } + sortedIndex -= 1; + } + + return answer; +} + +void main() { + test('test case 1', () { + expect(sortedSquaredArray([-1, -1, 2, 3, 3, 3, 4]), [1, 1, 4, 9, 9, 9, 16]); + }); + + test('test case 2', () { + expect(sortedSquaredArray([0]), [0]); + }); + + test('test case 2', () { + expect(sortedSquaredArray([-7, -6, -5, -4, -3, -2, -1]), [ + 1, + 4, + 9, + 16, + 25, + 36, + 49, + ]); + }); + + test('test case 4', () { + expect(sortedSquaredArray([1, 2, 3, 4, 5, 6, 7]), [ + 1, + 4, + 9, + 16, + 25, + 36, + 49, + ]); + }); +} diff --git a/array/two_sum.dart b/array/two_sum.dart new file mode 100644 index 00000000..29994eee --- /dev/null +++ b/array/two_sum.dart @@ -0,0 +1,26 @@ +import 'package:test/test.dart'; + +bool twoSum(List nums, int target) { + Map seen = {}; + for (int index = 0; index < nums.length; ++index) { + int number = nums[index]; + + int complement = target - number; + if (seen.containsKey(complement)) { + return true; + } else { + seen[number] = index; + } + } + return false; +} + +void main() { + test('test 1', () { + expect(twoSum([1, 2, 3, 4], 7), isTrue); + }); + + test('test 2', () { + expect(twoSum([1, 2, 3, 4], 12), isFalse); + }); +} diff --git a/array/validate_subsequence.dart b/array/validate_subsequence.dart new file mode 100644 index 00000000..b9063e92 --- /dev/null +++ b/array/validate_subsequence.dart @@ -0,0 +1,68 @@ +import 'package:test/test.dart'; + +bool checkIsSubSequence(List array, List sequence) { + if (array.isEmpty) { + return false; + } + + if (sequence.isEmpty) { + return true; + } + int arrayIndex = 0; + int sequenceIndex = 0; + + while (sequenceIndex < sequence.length && arrayIndex < array.length) { + if (sequence[sequenceIndex] == array[arrayIndex]) { + sequenceIndex += 1; + } + arrayIndex += 1; + } + return sequenceIndex == sequence.length; +} + +void main() { + List array; + List sequence; + + test('test 1', () { + array = [5, 1, 22, 25, 6, -1, 8, 10]; + sequence = [1, 6, -1, 10]; + expect(checkIsSubSequence(array, sequence), isTrue); + }); + + test('test 2', () { + array = [5, 1, 22, 25, 6, -1, 8, 10]; + sequence = [5, -1, 8, 10]; + expect(checkIsSubSequence(array, sequence), isTrue); + }); + + test('test 3', () { + array = [1, 1, 1, 1, 1]; + sequence = [0, 0, 0, 0]; + expect(checkIsSubSequence(array, sequence), isFalse); + }); + + test('test 4', () { + array = [1, 6, -1, 10]; + sequence = [1, 6, -1, 10]; + expect(checkIsSubSequence(array, sequence), isTrue); + }); + + test('test 5', () { + array = [1, 1, 6, 1]; + sequence = [0]; + expect(checkIsSubSequence(array, sequence), isFalse); + }); + + test('test 6', () { + array = []; + sequence = [0]; + expect(checkIsSubSequence(array, sequence), isFalse); + }); + + test('test 7', () { + array = [1, 1, 6, 1]; + sequence = []; + expect(checkIsSubSequence(array, sequence), isTrue); + }); +} diff --git a/backtracking/n-queen.dart b/backtracking/n-queen.dart new file mode 100644 index 00000000..38c2552b --- /dev/null +++ b/backtracking/n-queen.dart @@ -0,0 +1,140 @@ +import 'package:test/test.dart'; + +/*N-Queens Problem + +N - Queens problem is to place n - queens in such a manner +on an n x n chessboard that no queens attack each other by being in the same row, column or diagonal +We have to find maximum no of solutions that are possible. +You can learn more about from the following link :https://www.geeksforgeeks.org/printing-solutions-n-queen-problem/ +.*/ + +// Chess board, A 2d List of integers + +List> board = []; + +// checking is it safe place for a queen ? + +/*size : no of rows or columns of the given chess board + for e.g if there is a 3*3 chessboard then size = 3*/ + +bool isSafe(int size, int row, int col) { + //checking column safe + for (int k = 0; k < row; k++) { + if (board[k][col] == 1) { + return false; + } + } + int i = row; + int j = col; + + //checking left diagonal safe + while (i >= 0 && j >= 0) { + if (board[i][j] == 1) { + return false; + } + j--; + i--; + } + //checking right diagonal safe + i = row; + j = col; + while (i >= 0 && j < size) { + if (board[i][j] == 1) { + return false; + } + j++; + i--; + } + return true; +} + +int solveNQueen(int row, int size) { + //base case + if (size == row) { + return 1; + } + //recursive case + int ways = 0; + for (int col = 0; col < size; col++) { + //whether the current i,j is safe or not + if (isSafe(size, row, col)) { + board[row][col] = 1; + ways += solveNQueen(row + 1, size); + + //backtrack + board[row][col] = 0; + } + } + return ways; +} + +//This Function is used to refilled board with default value for testing purpose only. +// You can remove it, if you are using single test case. +void resetBoard(int boardSize) { + board = List.generate(boardSize, (i) => List.generate(boardSize, (j) => 0)); +} + +void main() { + /* + Test Cases + Size Expected Values + 1 : 1 + 2 : 0 + 3 : 0 + 4 : 2 + 5 : 10 + 6 : 4 + 7 : 40 + 8 : 92 + 9 : 352 + 10 : 724 + + */ + test("N Queen #testcase 1", () { + resetBoard(1); + expect(solveNQueen(0, 1), equals(1)); + }); + + test("N Queen #testcase 2", () { + resetBoard(2); + expect(solveNQueen(0, 2), equals(0)); + }); + + test("N Queen #testcase 3", () { + resetBoard(3); + expect(solveNQueen(0, 3), equals(0)); + }); + + test("N Queen #testcase 4", () { + resetBoard(4); + expect(solveNQueen(0, 4), equals(2)); + }); + + test("N Queen #testcase 5", () { + resetBoard(5); + expect(solveNQueen(0, 5), equals(10)); + }); + + test("N Queen #testcase 6", () { + resetBoard(6); + expect(solveNQueen(0, 6), equals(4)); + }); + + test("N Queen #testcase 7", () { + resetBoard(7); + expect(solveNQueen(0, 7), equals(40)); + }); + + test("N Queen #testcase 8", () { + resetBoard(8); + expect(solveNQueen(0, 8), equals(92)); + }); + test("N Queen #testcase 9", () { + resetBoard(9); + expect(solveNQueen(0, 9), equals(352)); + }); + test("N Queen #testcase 10", () { + resetBoard(10); + expect(solveNQueen(0, 10), equals(724)); + }); +} diff --git a/backtracking/open_knight_tour.dart b/backtracking/open_knight_tour.dart new file mode 100644 index 00000000..6825fe80 --- /dev/null +++ b/backtracking/open_knight_tour.dart @@ -0,0 +1,170 @@ +import 'dart:io'; + +import 'package:test/test.dart'; + +List> getValidPos(List position, int n) { + final i = position[0]; + final j = position[1]; + final positions = [ + [i + 1, j + 2], + [i - 1, j + 2], + [i + 1, j - 2], + [i - 1, j - 2], + [i + 2, j + 1], + [i + 2, j - 1], + [i - 2, j + 1], + [i - 2, j - 1], + ]; + + final List> permissiblePositions = []; + for (final currPosition in positions) { + final iTest = currPosition[0]; + final jTest = currPosition[1]; + if (0 <= iTest && iTest < n && 0 <= jTest && jTest < n) { + permissiblePositions.add(currPosition); + } + } + return permissiblePositions; +} + +bool isComplete(List> board) { + for (final row in board) { + for (final elem in row) { + if (elem == 0) { + return false; + } + } + } + return true; +} + +bool openKnightTourHelper(List> board, List pos, int curr) { + if (isComplete(board)) { + return true; + } + + for (final position in getValidPos(pos, board.length)) { + final i = position[0]; + final j = position[1]; + + if (board[i][j] == 0) { + board[i][j] = curr + 1; + if (openKnightTourHelper(board, position, curr + 1)) { + return true; + } + board[i][j] = 0; + } + } + return false; +} + +List> openKnightTour(int n) { + // board creation + final List> board = []; + for (var i = 0; i < n; i++) { + final List row = []; + for (var j = 0; j < n; j++) { + row.add(0); + } + board.add(row); + } + // open knight tour with backtracking + for (var i = 0; i < n; i++) { + for (var j = 0; j < n; j++) { + board[i][j] = 1; + if (openKnightTourHelper(board, [i, j], 1)) { + return board; + } + board[i][j] = 0; + } + } + return board; +} + +void printBoard(List> board) { + for (final row in board) { + for (final elem in row) { + stdout.write(elem); + } + stdout.write("\n"); + } + stdout.write("\n"); +} + +void main() { + test(('getValidPos: testCase #1'), () { + expect( + getValidPos([1, 3], 4), + equals([ + [2, 1], + [0, 1], + [3, 2], + ]), + ); + }); + + test(('getValidPos: testCase #3'), () { + expect( + getValidPos([1, 2], 5), + equals([ + [2, 4], + [0, 4], + [2, 0], + [0, 0], + [3, 3], + [3, 1], + ]), + ); + }); + + test(('isComplete: testCase #1'), () { + expect( + isComplete([ + [1], + ]), + equals(true), + ); + }); + + test(('isComplete: testCase #2'), () { + expect( + isComplete([ + [1, 2], + [3, 0], + ]), + equals(false), + ); + }); + + test(('openKnightTour: testCase #1'), () { + expect( + openKnightTour(1), + equals([ + [1], + ]), + ); + }); + + test(('openKnightTour: testCase #2'), () { + expect( + openKnightTour(2), + equals([ + [0, 0], + [0, 0], + ]), + ); + }); + + test(('openKnightTour: testCase #3'), () { + expect( + openKnightTour(5), + equals([ + [1, 14, 19, 8, 25], + [6, 9, 2, 13, 18], + [15, 20, 7, 24, 3], + [10, 5, 22, 17, 12], + [21, 16, 11, 4, 23], + ]), + ); + }); +} diff --git a/conversions/Decimal_To_Any.dart b/conversions/Decimal_To_Any.dart new file mode 100644 index 00000000..4dfdaed7 --- /dev/null +++ b/conversions/Decimal_To_Any.dart @@ -0,0 +1,71 @@ +//Convert a Decimal Number to Any Other Representation +//https://en.wikipedia.org/wiki/Positional_notation#Base_conversion + +import 'package:test/expect.dart'; +import 'package:test/scaffolding.dart'; + +String decimalToAny(int value, int base) { + var ALPHABET_VALUES = { + 10: 'A', + 11: 'B', + 12: 'C', + 13: 'D', + 14: 'E', + 15: 'F', + 16: 'G', + 17: 'H', + 18: 'I', + 19: 'J', + 20: 'K', + 21: 'L', + 22: 'M', + 23: 'N', + 24: 'O', + 25: 'P', + 26: 'Q', + 27: 'R', + 28: 'S', + 29: 'T', + 30: 'U', + 31: 'V', + 32: 'W', + 33: 'X', + 34: 'Y', + 35: 'Z', + }; + + if (value == 0) return "0"; + + if (base < 2 || base > 36) throw FormatException("Base not supported!"); + + bool negative = false; + if (value < 0) { + negative = true; + value *= -1; + } + + String output = ""; + while (value > 0) { + int remainder = value % base; + value = value ~/ base; + output = + (remainder < 10 + ? remainder.toString() + : ALPHABET_VALUES[remainder] ?? '0') + + output; + } + + return negative ? '-' + output : output; +} + +void main() { + test('test case 1', () => expect(decimalToAny(0, 2), '0')); + test('test case 2', () => expect(decimalToAny(5, 4), '11')); + test('test case 3', () => expect(decimalToAny(20, 3), '202')); + test('test case 4', () => expect(decimalToAny(-58, 16), '-3A')); + test('test case 5', () => expect(decimalToAny(243, 17), 'E5')); + test('test case 6', () => expect(decimalToAny(34923, 36), 'QY3')); + test('test case 7', () => expect(decimalToAny(10, 11), 'A')); + test('test case 8', () => expect(decimalToAny(-16, 16), '-10')); + test('test case 9', () => expect(decimalToAny(36, 36), '10')); +} diff --git a/conversions/Decimal_To_Binary.dart b/conversions/Decimal_To_Binary.dart index 09fc423f..f871fa8c 100644 --- a/conversions/Decimal_To_Binary.dart +++ b/conversions/Decimal_To_Binary.dart @@ -8,18 +8,18 @@ import "dart:math" show pow; * to a binary number using a bitwise * algorithm */ -void bitwiseConversion(var n){ - int b = 0,c = 0,d; +void bitwiseConversion(var n) { + int b = 0, c = 0, d; print("Bitwise conversion.\n"); - while(n != 0){ + while (n != 0) { d = (n & 1); - b += d * (pow(10,c++).toInt()); + b += d * (pow(10, c++).toInt()); n >>= 1; } print("\tBinary number: $b"); } //Main method -void main(){ +void main() { bitwiseConversion(8); } diff --git a/conversions/Decimal_to_Hexadecimal.dart b/conversions/Decimal_to_Hexadecimal.dart new file mode 100644 index 00000000..b6f4ab83 --- /dev/null +++ b/conversions/Decimal_to_Hexadecimal.dart @@ -0,0 +1,37 @@ +Map hex_table = { + "10": "A", + "11": "B", + "12": "C", + "13": "D", + "14": "E", + "15": "F", +}; +void main() { + print(decimal_to_hexadecimal(-123)); + print(decimal_to_hexadecimal(0)); + print(decimal_to_hexadecimal(404)); +} + +String decimal_to_hexadecimal(int decimal_val) { + if (decimal_val == 0) { + return "0"; + } + bool negative = false; + if (decimal_val < 0) { + negative = true; + decimal_val *= -1; + } + String hex_string = ""; + while (decimal_val > 0) { + String hex_val = ""; + int remainder = decimal_val % 16; + decimal_val = decimal_val ~/ 16; + if (hex_table.containsKey(remainder.toString())) { + hex_val = hex_table[remainder.toString()] ?? ''; + } else { + hex_val = remainder.toString(); + } + hex_string = hex_val + hex_string; + } + return negative ? "-" + hex_string : hex_string; +} diff --git a/conversions/Decimal_to_Octal.dart b/conversions/Decimal_to_Octal.dart new file mode 100644 index 00000000..a1d3cadf --- /dev/null +++ b/conversions/Decimal_to_Octal.dart @@ -0,0 +1,23 @@ +void main() { + print(decimal_to_octal(-123)); + print(decimal_to_octal(0)); + print(decimal_to_octal(404)); +} + +String decimal_to_octal(int decimal_val) { + if (decimal_val == 0) { + return "0"; + } + bool negative = false; + if (decimal_val < 0) { + negative = true; + decimal_val *= -1; + } + String oct_string = ""; + while (decimal_val > 0) { + int remainder = decimal_val % 8; + decimal_val = decimal_val ~/ 8; + oct_string = remainder.toString() + oct_string; + } + return negative ? "-" + oct_string : oct_string; +} diff --git a/conversions/Integer_To_Roman.dart b/conversions/Integer_To_Roman.dart new file mode 100644 index 00000000..f15d37ff --- /dev/null +++ b/conversions/Integer_To_Roman.dart @@ -0,0 +1,67 @@ +///Author: Shawn +///Email: stepfencurryxiao@gmail.com + +/* + * + * Concerting Integers into Roman Numerals + * + */ + +List ArabianRomanNumbers = [ + 1000, + 900, + 500, + 400, + 100, + 90, + 50, + 40, + 10, + 9, + 5, + 4, + 1, +]; + +List RomanNumbers = [ + "M", + "CM", + "D", + "CD", + "C", + "XC", + "L", + "XL", + "X", + "IX", + "V", + "IV", + "I", +]; + +List integer_to_roman(int num) { + if (num < 0) { + return []; + } + + List result = []; + for (int i = 0; i < ArabianRomanNumbers.length; i++) { + int times = num ~/ ArabianRomanNumbers[i]; + for (int j = 0; j < times; j++) { + print(RomanNumbers[i]); + } + num -= times * ArabianRomanNumbers[i]; + } + + return result; +} + +int main() { + /* IV */ + integer_to_roman(4); + /* II */ + integer_to_roman(2); + /* M */ + integer_to_roman(1000); + return 0; +} diff --git a/conversions/binary_to_decimal.dart b/conversions/binary_to_decimal.dart new file mode 100644 index 00000000..e39bcaf9 --- /dev/null +++ b/conversions/binary_to_decimal.dart @@ -0,0 +1,36 @@ +import "dart:math" show pow; + +import 'package:test/test.dart'; + +int binaryToDecimal(String binaryString) { + binaryString = binaryString.trim(); + if (binaryString == "") { + throw FormatException("An empty value was passed to the function"); + } + bool isNegative = binaryString[0] == "-"; + if (isNegative) binaryString = binaryString.substring(1); + int decimalValue = 0; + for (int i = 0; i < binaryString.length; i++) { + if ("01".contains(binaryString[i]) == false) { + throw FormatException("Non-binary value was passed to the function"); + } else { + decimalValue += + (pow(2, binaryString.length - i - 1).toInt() * + (int.tryParse(binaryString[i]) ?? 0)); + } + } + return isNegative ? -1 * decimalValue : decimalValue; +} + +void main() { + test('test case 1', () { + expect(binaryToDecimal("-111"), -7); + }); + test('test case 2', () { + expect(binaryToDecimal("101011"), 43); + }); + + test('test case 3', () { + expect(() => binaryToDecimal("1a1"), throwsFormatException); + }); +} diff --git a/conversions/binary_to_hexadecimal.dart b/conversions/binary_to_hexadecimal.dart new file mode 100644 index 00000000..849acd4c --- /dev/null +++ b/conversions/binary_to_hexadecimal.dart @@ -0,0 +1,78 @@ +import 'package:test/test.dart'; + +//Binary number to hexadecimal number conversion +Map hexTable = { + "0000": '0', + "0001": '1', + "0010": '2', + "0011": '3', + "0100": '4', + "0101": '5', + "0110": '6', + "0111": '7', + "1000": '8', + "1001": '9', + "1010": 'A', + "1011": 'B', + "1100": 'C', + "1101": 'D', + "1110": 'E', + "1111": 'F', +}; + +// function to take a binary string and to return hex value +String binaryToHexadecimal(String binaryString) { + // checking for unexpected values + binaryString = binaryString.trim(); + if (binaryString.isEmpty) { + throw new FormatException("An empty value was passed to the function"); + } + try { + int.parse(binaryString); + } catch (e) { + throw new FormatException("An invalid value was passed to the function"); + } + + // negative number check + bool isNegative = binaryString[0] == "-"; + if (isNegative) binaryString = binaryString.substring(1); + + // add min 0's in the end to make right substring length divisible by 4 + var binaryStringLength = binaryString.length; + for (int i = 1; i <= (4 - binaryStringLength % 4) % 4; i++) + binaryString = '0' + binaryString; + + // coverting the binary values to hex by diving into substring + String hexValue = ""; + int i = 0; + while (i != binaryString.length) { + String bin_curr = binaryString.substring(i, i + 4); + hexValue += hexTable[bin_curr] ?? ''; + i += 4; + } + + // returning the value + if (isNegative) { + return "-" + hexValue; + } + return hexValue; +} + +// driver function +void main() { + test("binary_to_hexadecimal -1111", () { + expect(binaryToHexadecimal("-1111"), equals("-F")); + }); + + test("binary_to_hexadecimal 101011", () { + expect(binaryToHexadecimal("101011"), equals("2B")); + }); + + test("binary_to_hexadecimal rasies error when number is invalid", () { + expect(() => binaryToHexadecimal("-1011a01"), throwsFormatException); + }); + + test("binary_to_hexadecimal of empty string raises error", () { + expect(() => binaryToHexadecimal(""), throwsFormatException); + }); +} diff --git a/conversions/binary_to_octal.dart b/conversions/binary_to_octal.dart new file mode 100644 index 00000000..4a68ab2d --- /dev/null +++ b/conversions/binary_to_octal.dart @@ -0,0 +1,54 @@ +import 'package:test/test.dart'; + +//Binary number to octal number conversion +void main() { + test("binary_to_octal -1111", () { + expect(binaryToOctal("-1111"), equals("-17")); + }); + + test("binary_to_octal 101011", () { + expect(binaryToOctal("101011"), equals("53")); + }); + + test("binary_to_octal rasies error when number is invalid", () { + expect(() => binaryToOctal("-1011a01"), throwsFormatException); + }); + + test("binary_to_octal of empty string raises error", () { + expect(() => binaryToOctal(""), throwsFormatException); + }); +} + +String binaryToOctal(String binaryString) { + binaryString = binaryString.trim(); + if (binaryString.isEmpty) { + throw new FormatException("An empty value was passed to the function"); + } + bool isNegative = binaryString[0] == "-"; + if (isNegative) binaryString = binaryString.substring(1); + + String octalValue = ""; + int binary; + try { + binary = int.parse(binaryString); + } catch (e) { + throw new FormatException("An invalid value was passed to the function"); + } + int currentBit; + int j = 1; + while (binary > 0) { + int code3 = 0; + for (int i = 0; i < 3; i++) { + currentBit = binary % 10; + binary = binary ~/ 10; + code3 += currentBit * j; + j *= 2; + } + octalValue = code3.toString() + octalValue; + j = 1; + } + if (isNegative) { + return "-" + octalValue; + } + return octalValue; +} diff --git a/conversions/hexadecimal_to_binary.dart b/conversions/hexadecimal_to_binary.dart new file mode 100644 index 00000000..5e1f5ed9 --- /dev/null +++ b/conversions/hexadecimal_to_binary.dart @@ -0,0 +1,70 @@ +import 'package:test/test.dart'; + +// hexadecimal number to binary number conversion +Map bin_table = { + "0": "0", + "1": "1", + "2": "10", + "3": "11", + "4": "100", + "5": "101", + "6": "110", + "7": "111", + "8": "1000", + "9": "1001", + "A": "1010", + "B": "1011", + "C": "1100", + "D": "1101", + "E": "1110", + "F": "1111", +}; + +// function to take hex value as string and return binary value as string +String hexadecimal_to_binary(String hex_value) { + // checking for unexpected values + hex_value = hex_value.trim(); + if (hex_value.isEmpty) { + throw new FormatException("An empty value was passed to the function"); + } + + // negative number check + bool is_negative = hex_value[0] == "-"; + if (is_negative) hex_value = hex_value.substring(1); + + // coverting the hex to binary values by diving into substring + String bin_val = ""; + int i = 0; + while (i != hex_value.length) { + String hex_cur = hex_value.substring(i, i + 1); + if (!bin_table.containsKey(hex_cur)) { + throw new FormatException("An invalid value was passed to the function"); + } + bin_val += bin_table[hex_cur] ?? ''; + i++; + } + + // returning the value + if (is_negative) { + return "-" + bin_val; + } + return bin_val; +} + +void main() { + test("hexadecimal_to_binary -F", () { + expect(hexadecimal_to_binary("-F"), equals("-1111")); + }); + + test("hexadecimal_to_binaryl 2B", () { + expect(hexadecimal_to_binary("2B"), equals("101011")); + }); + + test("hexadecimal_to_binary rasies error when number is invalid", () { + expect(() => hexadecimal_to_binary("AIO"), throwsFormatException); + }); + + test("hexadecimal_to_binary of empty string raises error", () { + expect(() => hexadecimal_to_binary(""), throwsFormatException); + }); +} diff --git a/conversions/hexadecimal_to_decimal.dart b/conversions/hexadecimal_to_decimal.dart new file mode 100644 index 00000000..416a8585 --- /dev/null +++ b/conversions/hexadecimal_to_decimal.dart @@ -0,0 +1,41 @@ +import "dart:math" show pow; + +Map hex_table = { + "A": 10, + "B": 11, + "C": 12, + "D": 13, + "E": 14, + "F": 15, +}; +void main() { + print(hexadecimal_to_decimal("1abc")); // 6844 + + print(hexadecimal_to_decimal(" -123 ")); // -291 + try { + print(hexadecimal_to_decimal("1x")); //error + } catch (ex) { + print(ex); + } +} + +int hexadecimal_to_decimal(String hex_string) { + hex_string = hex_string.trim().toUpperCase(); + if (hex_string == "") { + throw Exception("An empty value was passed to the function"); + } + bool is_negative = hex_string[0] == "-"; + if (is_negative) hex_string = hex_string.substring(1); + int decimal_val = 0; + for (int i = 0; i < hex_string.length; i++) { + if (int.tryParse(hex_string[i]) == null && + hex_table.containsKey(hex_string[i]) == false) { + throw Exception("Non-hex value was passed to the function"); + } else { + decimal_val += + pow(16, hex_string.length - i - 1).toInt() * + (int.tryParse(hex_string[i]) ?? hex_table[hex_string[i]] ?? 0); + } + } + return is_negative ? -1 * decimal_val : decimal_val; +} diff --git a/conversions/hexadecimal_to_octal.dart b/conversions/hexadecimal_to_octal.dart new file mode 100644 index 00000000..c72e29c2 --- /dev/null +++ b/conversions/hexadecimal_to_octal.dart @@ -0,0 +1,105 @@ +import "dart:math" show pow; +import 'package:test/test.dart'; + +// Hexadecimal number to octal number conversion program +String hexadecimal_to_octal(String hex_val) { + int dec = 0; + + // checking for null string passed to function + if (hex_val == "") { + throw new FormatException("An empty value was passed to the function"); + } + + // negative number check + bool is_negative = hex_val[0] == "-"; + if (is_negative) hex_val = hex_val.substring(1); + int c = hex_val.length - 1; + + // finding the decimal equivalent of the hexa decimal number + for (int i = 0; i < hex_val.length; i++) { + var ch = hex_val.substring(i, i + 1); + switch (ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + dec = dec + (int.tryParse(ch) ?? 0) * pow(16, c).toInt(); + c--; + break; + case 'a': + case 'A': + dec = dec + 10 * pow(16, c).toInt(); + c--; + break; + case 'b': + case 'B': + dec = dec + 11 * pow(16, c).toInt(); + c--; + break; + case 'c': + case 'C': + dec = dec + 12 * pow(16, c).toInt(); + c--; + break; + case 'd': + case 'D': + dec = dec + 13 * pow(16, c).toInt(); + c--; + break; + case 'e': + case 'E': + dec = dec + 14 * pow(16, c).toInt(); + c--; + break; + case 'f': + case 'F': + dec = dec + 15 * pow(16, c).toInt(); + c--; + break; + default: + throw new FormatException( + "An invalid value was passed to the function", + ); + } + } + + // String oct to store the octal equivalent of a hexadecimal number. + String oct_val = ""; + + // Converting decimal to octal number. + while (dec > 0) { + oct_val = (dec % 8).toString() + oct_val; + dec = dec ~/ 8; + } + + // Returning the value + if (is_negative) { + return "-" + oct_val; + } + return oct_val; +} + +void main() { + // Test cases with various input + test("hexadecimal_to_octal 43DF", () { + expect(hexadecimal_to_octal("43DF"), equals("41737")); + }); + + test("hexadecimal_to_octal -2CB", () { + expect(hexadecimal_to_octal("-2CB"), equals("-1313")); + }); + + test("hexadecimal_to_octal rasies error when number is invalid", () { + expect(() => hexadecimal_to_octal("AIO"), throwsFormatException); + }); + + test("hexadecimal_to_octal of empty string raises error", () { + expect(() => hexadecimal_to_octal(""), throwsFormatException); + }); +} diff --git a/conversions/octal_to_binary.dart b/conversions/octal_to_binary.dart new file mode 100644 index 00000000..d791e173 --- /dev/null +++ b/conversions/octal_to_binary.dart @@ -0,0 +1,74 @@ +import "dart:math" show pow; +import 'package:test/test.dart'; + +// octal number to binary number conversion +String ocatal_to_binary(String oct_val) { + // checking for unexpected values + oct_val = oct_val.trim(); + if (oct_val.isEmpty) { + throw new FormatException("An empty value was passed to the function"); + } + + // negative number check + bool is_negative = oct_val[0] == "-"; + if (is_negative) oct_val = oct_val.substring(1); + + int oct; + try { + oct = int.parse(oct_val); + } catch (e) { + throw new FormatException("An invalid value was passed to the function"); + } + + // checking number not valid for octal is passed(0-7) + for (int i = 0; i < oct_val.length; i++) { + if (!(int.parse(oct_val.substring(i, i + 1)) < 8)) { + throw new FormatException("An invalid value was passed to the function"); + } + ; + } + + // converting octal to decimal + int dec_val = 0, i = 0, bin_val = 0; + while (oct != 0) { + dec_val = dec_val + ((oct % 10) * pow(8, i).toInt()); + i++; + oct = oct ~/ 10; + } + + // converting to decimal to binary + i = 1; + while (dec_val != 0) { + bin_val = bin_val + (dec_val % 2) * i; + dec_val = dec_val ~/ 2; + i = i * 10; + } + + // returning the value + if (is_negative) { + return "-" + bin_val.toString(); + } + return bin_val.toString(); +} + +void main() { + test("ocatal_to_binary 75", () { + expect(ocatal_to_binary("75"), equals("111101")); + }); + + test("ocatal_to_binary -62", () { + expect(ocatal_to_binary("-62"), equals("-110010")); + }); + + test("ocatal_to_binary rasies error when number is invalid", () { + expect(() => ocatal_to_binary("84"), throwsFormatException); + }); + + test("ocatal_to_binary rasies error when number is invalid", () { + expect(() => ocatal_to_binary("as23"), throwsFormatException); + }); + + test("ocatal_to_binary of empty string raises error", () { + expect(() => ocatal_to_binary(""), throwsFormatException); + }); +} diff --git a/conversions/octal_to_decimal.dart b/conversions/octal_to_decimal.dart new file mode 100644 index 00000000..fca99245 --- /dev/null +++ b/conversions/octal_to_decimal.dart @@ -0,0 +1,70 @@ +import "dart:math" show pow; +import 'package:test/test.dart'; + +// octal number to decimal number conversion +// +// function to take oct string value and return decmal string value +String ocatal_to_decimal(String oct_val) { + // checking for unexpected values + oct_val = oct_val.trim(); + if (oct_val.isEmpty) { + throw new FormatException("An empty value was passed to the function"); + } + + // negative number check + bool is_negative = oct_val[0] == "-"; + if (is_negative) oct_val = oct_val.substring(1); + + int oct; + try { + oct = int.parse(oct_val); + } catch (e) { + throw new FormatException("An invalid value was passed to the function"); + } + + // checking number not valid for octal is passed(0-7) + for (int i = 0; i < oct_val.length; i++) { + if (!(int.parse(oct_val.substring(i, i + 1)) < 8)) { + throw new FormatException("An invalid value was passed to the function"); + } + ; + } + + // converting octal to decimal + int dec_val = 0, i = 0; + while (oct != 0) { + dec_val = dec_val + ((oct % 10) * pow(8, i).toInt()); + i++; + oct = oct ~/ 10; + } + + // returning the value + if (is_negative) { + return "-" + dec_val.toString(); + } + return dec_val.toString(); +} + +// driver function +void main() { + // test cases for different input + test("ocatal_to_decimal 75", () { + expect(ocatal_to_decimal("75"), equals("61")); + }); + + test("ocatal_to_decimal -62", () { + expect(ocatal_to_decimal("-62"), equals("-50")); + }); + + test("ocatal_to_decimal rasies error when number is invalid", () { + expect(() => ocatal_to_decimal("84"), throwsFormatException); + }); + + test("ocatal_to_decimal rasies error when number is invalid", () { + expect(() => ocatal_to_decimal("as23"), throwsFormatException); + }); + + test("ocatal_to_decimal of empty string raises error", () { + expect(() => ocatal_to_decimal(""), throwsFormatException); + }); +} diff --git a/conversions/octal_to_hexadecimal.dart b/conversions/octal_to_hexadecimal.dart new file mode 100644 index 00000000..5b1b3885 --- /dev/null +++ b/conversions/octal_to_hexadecimal.dart @@ -0,0 +1,95 @@ +import "dart:math" show pow; +import 'package:test/test.dart'; + +// octal number to hex number +Map hex_table = { + "10": "A", + "11": "B", + "12": "C", + "13": "D", + "14": "E", + "15": "F", +}; +// +// function take octal string value and return hexadecimal string value +String ocatal_to_hex(String oct_val) { + // checking for unexpected values + oct_val = oct_val.trim(); + if (oct_val == "") { + throw new FormatException("An empty value was passed to the function"); + } + + // negative number check + bool is_negative = oct_val[0] == "-"; + if (is_negative) oct_val = oct_val.substring(1); + + int oct; + try { + oct = int.parse(oct_val); + } catch (e) { + throw new FormatException("An invalid value was passed to the function"); + } + + // checking number not valid for octal is passed(0-7) + for (int i = 0; i < oct_val.length; i++) { + if (!(int.parse(oct_val.substring(i, i + 1)) < 8)) { + throw new FormatException("An invalid value was passed to the function"); + } + ; + } + + // converting octal to decimal + int dec_val = 0, i = 0; + while (oct != 0) { + dec_val = dec_val + ((oct % 10) * pow(8, i).toInt()); + i++; + oct = oct ~/ 10; + } + + // converting to decimal to hex + if (dec_val == 0) { + return "0"; + } + String hex_string = ""; + while (dec_val > 0) { + String hex_val = ""; + int remainder = dec_val % 16; + dec_val = dec_val ~/ 16; + if (hex_table.containsKey(remainder.toString())) { + hex_val = hex_table[remainder.toString()] ?? ''; + } else { + hex_val = remainder.toString(); + } + hex_string = hex_val + hex_string; + } + + // returning the value + if (is_negative) { + return "-" + hex_string; + } + return hex_string; +} + +// driver function +void main() { + // test input + test("ocatal_to_hex 75", () { + expect(ocatal_to_hex("75"), equals("3D")); + }); + + test("ocatal_to_hex -62", () { + expect(ocatal_to_hex("-62"), equals("-32")); + }); + + test("ocatal_to_hex rasies error when number is invalid", () { + expect(() => ocatal_to_hex("84"), throwsFormatException); + }); + + test("ocatal_to_hex rasies error when number is invalid", () { + expect(() => ocatal_to_hex("as23"), throwsFormatException); + }); + + test("ocatal_to_hex of empty string raises error", () { + expect(() => ocatal_to_hex(""), throwsFormatException); + }); +} diff --git a/conversions/roman_to_integer.dart b/conversions/roman_to_integer.dart new file mode 100644 index 00000000..95d21b86 --- /dev/null +++ b/conversions/roman_to_integer.dart @@ -0,0 +1,68 @@ +import 'package:test/test.dart'; + +int romanToInteger(var s) { + int ans = 0; + for (int i = 0; i < s.length; i++) { + int num1 = value(s[i]); + if (i + 1 < s.length) { + int num2 = value(s[i + 1]); + if (num1 < num2) { + ans = ans + num2 - num1; + i++; + } else { + ans = ans + num1; + } + } else { + ans = ans + num1; + } + } + return ans; +} + +int value(var r) { + if (r == 'I') + return 1; + else if (r == 'V') + return 5; + else if (r == 'X') + return 10; + else if (r == 'L') + return 50; + else if (r == 'C') + return 100; + else if (r == 'D') + return 500; + else if (r == 'M') + return 1000; + return 0; +} + +void main() { + test("romanToInteger XII returns 12", () { + expect(romanToInteger('XII'), equals(12)); + }); + + test("romanToInteger LII returns 52", () { + expect(romanToInteger('LII'), equals(52)); + }); + + test("romanToInteger DLVII returns 557", () { + expect(romanToInteger('LII'), equals(52)); + }); + + test("romanToInteger VI returns 6", () { + expect(romanToInteger('VI'), equals(6)); + }); + + test("romanToInteger CLXV returns 165", () { + expect(romanToInteger('CLXV'), equals(165)); + }); + + test("romanToInteger MDCI returns 1601", () { + expect(romanToInteger('MDCI'), equals(1601)); + }); + + test("romanToInteger LVII returns 57", () { + expect(romanToInteger('LVII'), equals(57)); + }); +} diff --git a/dart_test.yaml b/dart_test.yaml new file mode 100644 index 00000000..53f6bf6c --- /dev/null +++ b/dart_test.yaml @@ -0,0 +1,3 @@ +paths: [.] + +filename: "*.dart" diff --git a/data_structures/HashMap/Hashing.dart b/data_structures/HashMap/Hashing.dart index 277248f8..59c5b6d7 100644 --- a/data_structures/HashMap/Hashing.dart +++ b/data_structures/HashMap/Hashing.dart @@ -1,57 +1,53 @@ +import 'package:test/test.dart'; + //Author:Shawn //Email:stepfencurryxiao@gmail.com -class Node{ - int data; - Node next; - - Node(int data){ +class Node { + int? data; + Node? next; + + Node(int data) { this.data = data; this.next = null; } } -class LinkedList{ - Node head; +class LinkedList { + Node? head; int size; - - LinkedList(){ + + LinkedList({this.size = 0}) { head = null; - size = 0; } - - void insert(int data){ - - Node temp = head; + + void insert(int data) { Node newnode = new Node(data); - + size++; - - if(head==null){ + + if (head == null) { head = newnode; - } - else{ + } else { newnode.next = head; head = newnode; } } - - void delete(int data){ - if(size == 0){ + + void delete(int data) { + if (size == 0) { print("underFlow!"); return; - } - else{ - Node curr = head; - if(curr.data == data){ - head = curr.next; + } else { + Node? curr = head; + if (curr?.data == data) { + head = curr?.next; size--; return; - } - else{ - while(curr.next.next != null){ - if(curr.next.data == data){ - curr.next = curr.next.next; + } else { + while (curr?.next?.next != null) { + if (curr?.next?.data == data) { + curr?.next = curr.next?.next; return; } } @@ -59,10 +55,10 @@ class LinkedList{ } } } - - void display(){ - Node temp = head; - while(temp != null){ + + void display() { + Node? temp = head; + while (temp != null) { print(temp.data.toString()); temp = temp.next; } @@ -70,66 +66,61 @@ class LinkedList{ } } -class HashMap{ +class HashMap { int hsize; List buckets; - - HashMap(int hsize){ - buckets = new List(hsize); - for(int i = 0;i < hsize;i++){ + + HashMap({this.hsize = 0, this.buckets = const []}) { + buckets = new List.generate(hsize, (a) => LinkedList()); + for (int i = 0; i < hsize; i++) { buckets[i] = new LinkedList(); } this.hsize = hsize; } - - int hashing(int key){ + + int hashing(int key) { int hash = key % hsize; - if(hash < 0){ + if (hash < 0) { hash += hsize; } return hash; } - - void insertHash(int key){ + + void insertHash(int key) { int hash = hashing(key); buckets[hash].insert(key); } - - void deleteHash(int key){ + + void deleteHash(int key) { int hash = hashing(key); buckets[hash].delete(key); } - - void displayHashtable(){ - for(int i = 0;i < hsize;i++){ + + void displayHashtable() { + for (int i = 0; i < hsize; i++) { print("Bucket $i:"); buckets[i].display(); } } } -void main(){ - - HashMap h = new HashMap(7); - - print("Add key 5"); - h.insertHash(5); - - print("Add key 28"); - h.insertHash(28); - - print("Add key 1"); - h.insertHash(1); - - print("Delete Key 28"); - h.deleteHash(28); - - print("Print Table:\n"); - h.displayHashtable(); - - print("Delete Key 1"); - h.deleteHash(1); - - print("Print Table:\n"); - h.displayHashtable(); +void main() { + test("Insert and Delete from HashMap", () { + HashMap h = new HashMap(hsize: 7); + + h.insertHash(5); + h.insertHash(28); + h.insertHash(1); + + expect(h.buckets[5].head?.data, equals(5)); + // 28 % 7 = 0 + expect(h.buckets[0].head?.data, equals(28)); + expect(h.buckets[1].head?.data, equals(1)); + + h.deleteHash(28); + expect(h.buckets[0].head, isNull); + + h.deleteHash(1); + expect(h.buckets[1].head, isNull); + }); } diff --git a/data_structures/HashMap/hashmap_implementation b/data_structures/HashMap/hashmap_implementation new file mode 100644 index 00000000..53ea7205 --- /dev/null +++ b/data_structures/HashMap/hashmap_implementation @@ -0,0 +1,73 @@ +import 'package:test/test.dart'; + +// Internal class to store each key-value pair and its next node +class Entry { + final K key; + V value; + Entry next; + + Entry(this.key, this.value, [this.next]); +} + +class HashMap { + // Internal list to store the keys and values + List> _table; + + HashMap() { + _table = List>.filled(256, null); + } + + // Helper function to generate a hash code for a key + int _hashCode(K key) { + return key.hashCode % _table.length; + } + + // Insert a new key-value pair into the hash map + void insert(K key, V value) { + final int index = _hashCode(key); + if (_table[index] == null) { + _table[index] = Entry(key, value); + } else { + Entry entry = _table[index]; + while (entry.next != null && entry.key != key) { + entry = entry.next; + } + if (entry.key == key) { + entry.value = value; + } else { + entry.next = Entry(key, value); + } + } + } + + // Get the value associated with a key in the hash map + V get(K key) { + final int index = _hashCode(key); + if (_table[index] == null) { + return null; + } else { + Entry entry = _table[index]; + while (entry != null && entry.key != key) { + entry = entry.next; + } + return entry?.value; + } + } +} + +void main() { + test('adding a key to a map', () { + HashMap map = HashMap(); + expect(map.get(1), null); + map.insert(1, 'Akash'); + expect(map.get(1), 'Akash'); + }); + + test('updating a key in a map', () { + HashMap map = HashMap(); + map.insert(1, 'Akash'); + expect(map.get(1), 'Akash'); + map.insert(1, 'IronMan'); + expect(map.get(1), 'IronMan'); + }); +} diff --git a/data_structures/Heap/Binary_Heap/Max_heap.dart b/data_structures/Heap/Binary_Heap/Max_heap.dart new file mode 100644 index 00000000..752d399a --- /dev/null +++ b/data_structures/Heap/Binary_Heap/Max_heap.dart @@ -0,0 +1,116 @@ +import 'package:test/test.dart'; + +class MaxHeap { + List heap = []; + + void buildHeap(List array) { + this.heap = _heapify(array); + } + + List _heapify(List array) { + int firstParent = (array.length - 2) ~/ 2; + for (int i = firstParent; i >= 0; i--) { + _siftDown(i, array.length - 1, array); + } + return array; + } + + int? peek() { + if (!isEmpty()) { + return this.heap[0]; + } + return null; + } + + bool isEmpty() { + return this.heap.length == 0; + } + + void _siftUp(int currentIndex) { + int parentIndex = (currentIndex - 1) ~/ 2; + while (parentIndex >= 0 && + this.heap[parentIndex] < this.heap[currentIndex]) { + _swap(parentIndex, currentIndex, this.heap); + currentIndex = parentIndex; + parentIndex = (currentIndex - 1) ~/ 2; + } + } + + void _siftDown(int currentIndex, int endIndex, List heap) { + int childOneIndex = (2 * currentIndex) + 1; + int childTwoIndex; + + while (childOneIndex <= endIndex) { + childTwoIndex = 2 * currentIndex + 2 <= endIndex + ? 2 * currentIndex + 2 + : -1; + int indexToSwap; + if (childTwoIndex != -1 && heap[childTwoIndex] > heap[childOneIndex]) { + indexToSwap = childTwoIndex; + } else { + indexToSwap = childOneIndex; + } + + if (heap[currentIndex] < heap[indexToSwap]) { + _swap(currentIndex, indexToSwap, heap); + currentIndex = indexToSwap; + childOneIndex = (2 * currentIndex) + 1; + } else { + break; + } + } + } + + void insert(int value) { + this.heap.add(value); + _siftUp(this.heap.length - 1); + } + + int? remove() { + if (!isEmpty()) { + _swap(0, this.heap.length - 1, this.heap); + int maxElement = this.heap.removeLast(); + _siftDown(0, this.heap.length - 1, this.heap); + return maxElement; + } + return null; + } + + void _swap(int left, int right, List array) { + int temp; + temp = array[left]; + array[left] = array[right]; + array[right] = temp; + } +} + +void main() { + MaxHeap maxHeap = new MaxHeap(); + List array = [48, 12, 24, 7, 8, -5, 24, 391, 24, 56, 2, 6, 8, 41]; + maxHeap.buildHeap(array); + test(('Test case 1'), () { + expect(maxHeap.remove(), equals(391)); + maxHeap.insert(-100); + expect(maxHeap.isEmpty(), isFalse); + expect(maxHeap.peek(), equals(56)); + maxHeap.insert(1000); + expect(maxHeap.peek(), equals(1000)); + expect(maxHeap.remove(), equals(1000)); + expect(maxHeap.remove(), equals(56)); + }); + + test(('Test case 2'), () { + array = [-7, 2, 3, 8, -10, 4, -6, -10, -2, -7, 10, 5, 2, 9, -9, -5, 3, 8]; + maxHeap = new MaxHeap(); + maxHeap.buildHeap(array); + expect(maxHeap.remove(), equals(10)); + expect(maxHeap.peek(), equals(9)); + maxHeap.insert(890); + expect(maxHeap.peek(), equals(890)); + expect(maxHeap.remove(), equals(890)); + expect(maxHeap.peek(), equals(9)); + expect(maxHeap.isEmpty(), isFalse); + maxHeap.insert(1); + expect(maxHeap.peek(), equals(9)); + }); +} diff --git a/data_structures/Heap/Binary_Heap/Min_Heap.dart b/data_structures/Heap/Binary_Heap/Min_Heap.dart index c12d7486..3b56f6ca 100644 --- a/data_structures/Heap/Binary_Heap/Min_Heap.dart +++ b/data_structures/Heap/Binary_Heap/Min_Heap.dart @@ -1,3 +1,5 @@ +import 'package:test/test.dart'; + //Author:Shawn //Email:stepfencurryxiao@gmail.com @@ -16,23 +18,24 @@ * leftcgild : 2n + 1 */ -List upAdjust(List arr,int length){ +List upAdjust(List arr, int length) { //Mark inserted nodes var child = length - 1; //Father nodes - int parent = ((child - 1) / 2).toInt(); + int parent = (child - 1) ~/ 2; //Save the inserted node temporarily int temp = arr[child]; - - while(child > 0 && temp < arr[parent]){ + + while (child > 0 && temp < arr[parent]) { //When temp finds the correct location, we will assign the value of temp to this node arr[child] = arr[parent]; child = parent; - parent = ((child - 1) / 2).toInt(); + parent = (child - 1) ~/ 2; } arr[child] = temp; return arr; } + /* * ** Sink operation, delete operation is equivalent to ** after an element is assigned to the root element, the sink operation is performed on the root element @@ -40,39 +43,40 @@ List upAdjust(List arr,int length){ *@ param parent subscript of element to sink *@ param length array length */ -List downAdjust(List arr,int parent,int length){ +List downAdjust(List arr, int parent, int length) { //Save elements to sink int temp = arr[parent]; //Locate left child node location int child = 2 * parent + 1; //Begin to sink while (child < length) { - //If the right child node is smaller than the left child, locate the right child - if (child + 1 < length && arr[child] > arr[child + 1]) { - child++; - } - //Sink ends if parent is smaller or equal to child - if (temp <= arr[child]) - break; - - arr[parent] = arr[child]; - parent = child; - child = 2 * parent + 1; + //If the right child node is smaller than the left child, locate the right child + if (child + 1 < length && arr[child] > arr[child + 1]) { + child++; + } + //Sink ends if parent is smaller or equal to child + if (temp <= arr[child]) break; + + arr[parent] = arr[child]; + parent = child; + child = 2 * parent + 1; } arr[parent] = temp; return arr; } -List buildHead(List arr,int length) { - //Sink from the last non leaf node - for (int i = ((length - 2) / 2).toInt(); i >= 0; i--) { - arr = downAdjust(arr, i, length); - } - return arr; +List buildHead(List arr, int length) { + //Sink from the last non leaf node + for (int i = (length - 2) ~/ 2; i >= 0; i--) { + arr = downAdjust(arr, i, length); + } + return arr; } -void main(){ - List arr = [1,3,0,5,4,6,7,8,9]; - List BinaryHeap = buildHead(arr,arr.length); - print(BinaryHeap); +void main() { + test("buildHead creates a min heap", () { + List arr = [1, 3, 0, 5, 4, 6, 7, 8, 9]; + List binaryHeap = buildHead(arr, arr.length); + expect(binaryHeap, equals([0, 3, 1, 5, 4, 6, 7, 8, 9])); + }); } diff --git a/data_structures/Heap/Binary_Heap/min_heap_two.dart b/data_structures/Heap/Binary_Heap/min_heap_two.dart new file mode 100644 index 00000000..6627b3c1 --- /dev/null +++ b/data_structures/Heap/Binary_Heap/min_heap_two.dart @@ -0,0 +1,115 @@ +import 'package:test/test.dart'; + +class MinHeap { + List heap = []; + + void buildHeap(List array) { + this.heap = _heapify(array); + } + + List _heapify(List array) { + int firstParent = (array.length - 2) ~/ 2; + for (int i = firstParent; i >= 0; i--) { + _siftDown(i, array.length - 1, array); + } + return array; + } + + int? peek() { + if (!isEmpty()) { + return this.heap[0]; + } + return null; + } + + bool isEmpty() { + return this.heap.length == 0; + } + + void _siftUp(int currentIndex) { + int parentIndex = (currentIndex - 1) ~/ 2; + while (parentIndex >= 0 && + this.heap[parentIndex] > this.heap[currentIndex]) { + _swap(parentIndex, currentIndex, this.heap); + currentIndex = parentIndex; + parentIndex = (currentIndex - 1) ~/ 2; + } + } + + void _siftDown(int currentIndex, int endIndex, List heap) { + int childOneIndex = (2 * currentIndex) + 1; + int childTwoIndex; + + while (childOneIndex <= endIndex) { + childTwoIndex = 2 * currentIndex + 2 <= endIndex + ? 2 * currentIndex + 2 + : -1; + int indexToSwap; + if (childTwoIndex != -1 && heap[childTwoIndex] < heap[childOneIndex]) { + indexToSwap = childTwoIndex; + } else { + indexToSwap = childOneIndex; + } + + if (heap[currentIndex] > heap[indexToSwap]) { + _swap(currentIndex, indexToSwap, heap); + currentIndex = indexToSwap; + childOneIndex = (2 * currentIndex) + 1; + } else { + break; + } + } + } + + void insert(int value) { + this.heap.add(value); + _siftUp(this.heap.length - 1); + } + + int? remove() { + if (!isEmpty()) { + _swap(0, this.heap.length - 1, this.heap); + int minElement = this.heap.removeLast(); + _siftDown(0, this.heap.length - 1, this.heap); + return minElement; + } + return null; + } + + void _swap(int left, int right, List array) { + int temp; + temp = array[left]; + array[left] = array[right]; + array[right] = temp; + } +} + +void main() { + MinHeap minheap = new MinHeap(); + List array = [48, 12, 24, 7, 8, -5, 24, 391, 24, 56, 2, 6, 8, 41]; + minheap.buildHeap(array); + test(('Test case 1'), () { + expect(minheap.remove(), equals(-5)); + expect(minheap.isEmpty(), isFalse); + minheap.insert(-100); + expect(minheap.peek(), equals(-100)); + minheap.insert(-100); + expect(minheap.remove(), equals(-100)); + expect(minheap.remove(), equals(-100)); + }); + + test(('Test case 2'), () { + array = [-7, 2, 3, 8, -10, 4, -6, -10, -2, -7, 10, 5, 2, 9, -9, -5, 3, 8]; + minheap = new MinHeap(); + minheap.buildHeap(array); + expect(minheap.remove(), equals(-10)); + expect(minheap.peek(), equals(-10)); + minheap.insert(-8); + expect(minheap.peek(), equals(-10)); + expect(minheap.remove(), equals(-10)); + expect(minheap.peek(), equals(-9)); + expect(minheap.isEmpty(), isFalse); + minheap.insert(-8); + expect(minheap.peek(), equals(-9)); + }); +} diff --git a/data_structures/Queue/Circular_Queue.dart b/data_structures/Queue/Circular_Queue.dart new file mode 100644 index 00000000..84e6bd3b --- /dev/null +++ b/data_structures/Queue/Circular_Queue.dart @@ -0,0 +1,108 @@ +import 'package:test/test.dart'; + +// author: kjain1810 +// reference: https://en.wikipedia.org/wiki/Circular_buffer +const int MAX_SIZE = 10; + +class CircularQueue { + int start = -1, end = -1; + List queue = List.filled(MAX_SIZE, null); + + // insert elements into the queue + void enque(T element) { + if (start == -1) { + start = 0; + end = 0; + queue[0] = element; + return; + } + if (end == MAX_SIZE - 1 && start == 0) { + print("The queue is full!!!"); + return; + } + if (end == start - 1) { + print("The queue is full!!!"); + return; + } + end++; + end %= MAX_SIZE; + queue[end] = element; + } + + // remove elements from the queue + T? deque() { + if (start == -1) { + print("The queue is empty!!!"); + return null; + } + T? here = queue[start]; + if (start == end) { + start = -1; + end = -1; + return here; + } + start++; + start %= MAX_SIZE; + return here; + } + + // get the size of the queue + int size() { + if (start == -1) return 0; + if (start < end) return end - start + 1; + return (MAX_SIZE - (start - end)); + } + + // print all the elements of the queue + void printAll() { + if (start == -1) { + print("The queue is empty!!!"); + return; + } + int i = start; + while (i != end) { + i++; + i %= MAX_SIZE; + print(queue[i]); + } + } +} + +void main() { + test("Initial CircularQueue is empty", () { + CircularQueue queue = new CircularQueue(); + + expect(queue.deque(), isNull); + }); + + test("deque return first item put to CircularQueue", () { + CircularQueue queue = new CircularQueue(); + queue.enque(1); + + expect(queue.deque(), equals(1)); + }); + + test("CircularQueue act as fifo", () { + CircularQueue queue = new CircularQueue(); + queue.enque(1); + queue.enque(2); + queue.enque(3); + + expect(queue.deque(), equals(1)); + expect(queue.deque(), equals(2)); + expect(queue.deque(), equals(3)); + }); + + test("deque returns null after removing all items", () { + CircularQueue queue = new CircularQueue(); + queue.enque(1); + queue.enque(2); + queue.enque(3); + + queue.deque(); + queue.deque(); + queue.deque(); + + expect(queue.deque(), isNull); + }); +} diff --git a/data_structures/Queue/List_Queue.dart b/data_structures/Queue/List_Queue.dart index 74db4de6..60153757 100644 --- a/data_structures/Queue/List_Queue.dart +++ b/data_structures/Queue/List_Queue.dart @@ -1,64 +1,68 @@ +import 'package:test/test.dart'; + //Author:Shawn //Email:stepfencurryxiao@gmail.com const int MAX_SIZE = 10; -class ListQueue{ - +class ListQueue { int count = 0; - List queue = new List(MAX_SIZE); - + List queue = List.filled(MAX_SIZE, null); + //Checks if the queue has elements (not empty) - bool hasElements(){ - if(queue.length == 0){ + bool hasElements() { + if (queue.length == 0) { return false; - } - else{ + } else { return true; } } - - //Add an elment to the queue - void enque(T elment){ - if(count == MAX_SIZE){ + + //Add an element to the queue + void enque(T element) { + if (count == MAX_SIZE) { print("The queue is full!!!"); - } - else{ - queue[count] = elment; + } else { + queue[count] = element; count++; } } - + //Takes the next element from the queue - T deque(){ - T result = null; - if(count == 0){ + T? deque() { + T? result = null; + if (count == 0) { print("The queue is empty!!!"); - } - else{ + } else { result = queue[0]; - for(int i = 0; i < queue.length - 1; i++){ + for (int i = 0; i < queue.length - 1; i++) { queue[i] = queue[i + 1]; } + count--; } return result; } } -void main(){ - ListQueue Queue = new ListQueue(); - Queue.enque(12); - Queue.enque(2); - Queue.enque(7); - print(Queue.queue); - print("Enque:"); - var returnData = Queue.deque(); - print("$returnData\n"); - print("Enque:"); - returnData = Queue.deque(); - print("$returnData\n"); - print("Enque:"); - returnData = Queue.deque(); - print("$returnData\n"); - print("Now the queue is: " + (Queue.queue).toString()); +void main() { + test("Enqueue and deque elements", () { + ListQueue queue = new ListQueue(); + + // Note: The original hasElements returns true if queue.length > 0, + // but queue is initialized with length MAX_SIZE (10), so it always returns true. + expect(queue.hasElements(), isTrue); + + queue.enque(12); + queue.enque(2); + queue.enque(7); + + expect(queue.queue.sublist(0, 3), equals([12, 2, 7])); + + expect(queue.deque(), equals(12)); + expect(queue.deque(), equals(2)); + expect(queue.deque(), equals(7)); + + // Deque on empty + expect(queue.deque(), isNull); + }); } diff --git a/data_structures/Queue/Priority_Queue.dart b/data_structures/Queue/Priority_Queue.dart new file mode 100644 index 00000000..30a89789 --- /dev/null +++ b/data_structures/Queue/Priority_Queue.dart @@ -0,0 +1,85 @@ +import 'package:test/test.dart'; + +class PriorityQueue { + List> _dataStore = >[]; + + int get size => _dataStore.length; + + bool get isEmpty => _dataStore.isEmpty; + + enqueue(T item, int priority) { + QueueItem queueItem = new QueueItem(item, priority); + bool added = false; + for (int i = 0; i < _dataStore.length; i++) { + if (priority < _dataStore[i].priority) { + added = true; + _dataStore.insert(i, queueItem); + break; + } + } + if (!added) { + _dataStore.add(queueItem); + } + } + + T? dequeue() { + if (_dataStore.isNotEmpty) { + return _dataStore.removeAt(0).item; + } + return null; + } + + T? get front { + if (_dataStore.isNotEmpty) { + return _dataStore.first.item; + } + return null; + } + + T? get end { + if (_dataStore.isNotEmpty) { + return _dataStore.last.item; + } + return null; + } + + clear() { + _dataStore.clear(); + } + + String toString() { + return _dataStore.toString(); + } +} + +class QueueItem { + T item; + int priority; + + QueueItem(this.item, this.priority); + + String toString() { + return '$item - $priority'; + } +} + +void main() { + test("Enqueue and dequeue based on priority", () { + PriorityQueue queue = new PriorityQueue(); + queue.enqueue(1, 2); + queue.enqueue(2, 1); + queue.enqueue(3, 3); + queue.enqueue(4, 2); + + expect(queue.size, equals(4)); + expect(queue.front, equals(2)); // priority 1 + + expect(queue.dequeue(), equals(2)); + expect(queue.dequeue(), equals(1)); // priority 2, enqueued first + expect(queue.dequeue(), equals(4)); // priority 2 + expect(queue.dequeue(), equals(3)); // priority 3 + + expect(queue.isEmpty, isTrue); + expect(queue.dequeue(), isNull); + }); +} diff --git a/data_structures/Stack/Array_Stack.dart b/data_structures/Stack/Array_Stack.dart index 4b8e481a..2d7136cd 100644 --- a/data_structures/Stack/Array_Stack.dart +++ b/data_structures/Stack/Array_Stack.dart @@ -1,63 +1,80 @@ -//Author: Shawn -//Email: stepfencurryxiao@gmail.com - -class ArrayStack{ - //stack - List stack; - //element of the stack - int count; - //size of stack - int n; - +import 'package:test/test.dart'; + +class ArrayStack { + /// [stack] + List _stack = []; + + /// [_count] is the number of element in the stack + int _count = 0; + + /// [_size] of stack + int _size = 0; + //Init the array stack - ArrayStack(var n){ - this.n = n; - this.stack = new List(n); - this.count = 0; + ArrayStack(int size) { + this._size = size; + this._stack = List.filled(_size, null); + this._count = 0; } - - //Push a item to the stack - void push(T item){ - if(count == n){ - print("The stack is full\n"); + + /// Push a item to the stack of type [T] to the [_stack] + /// if the size is exceeded the element wont be added. + void push(T item) { + if (_count == _size) { + return null; } - stack[count] = item; - count++; + _stack[_count] = item; + _count++; } - - //Pop a item from the stack - T pop(){ - if(count == 0){ - print("No data in the stack!\n"); + + /// Pop the last element inserted from the [_stack]. + T? pop() { + if (_count == 0) { + return null; } - T pop_data = stack[count - 1]; - stack[count - 1] = null; - count--; + T? pop_data = _stack[_count - 1]; + _stack[_count - 1] = null; + _count--; return pop_data; } - - void Display(){ - print("ArrayStack: $stack\n"); + + List get stack { + return _stack; } } -void main(){ - ArrayStack array_stack = new ArrayStack(6); - - array_stack.push('1'); - array_stack.push("2"); - array_stack.push('3'); - array_stack.push("4"); - array_stack.push('5'); - array_stack.push("6"); - - array_stack.Display(); - - var pop_data; - pop_data = array_stack.pop(); - print("Pop $pop_data from stack\n"); - pop_data = array_stack.pop(); - print("Pop $pop_data from stack\n"); - print("Now the stock:"); - array_stack.Display(); -} \ No newline at end of file +void main() { + test('test case 1: push and get stack', () { + ArrayStack arrayStack = new ArrayStack(6); + arrayStack.push('1'); + arrayStack.push("2"); + arrayStack.push('3'); + arrayStack.push("4"); + arrayStack.push('5'); + arrayStack.push("6"); + expect(arrayStack.stack, equals(['1', '2', '3', '4', '5', '6'])); + }); + + test('test case 2: pop stack items', () { + ArrayStack arrayStack = new ArrayStack(6); + arrayStack.push('1'); + arrayStack.push("2"); + arrayStack.push('3'); + arrayStack.push("4"); + arrayStack.push('5'); + arrayStack.push("6"); + + expect(arrayStack.pop(), equals('6')); + expect(arrayStack.pop(), equals('5')); + expect(arrayStack.pop(), equals('4')); + expect(arrayStack.pop(), equals('3')); + expect(arrayStack.pop(), equals('2')); + expect(arrayStack.pop(), equals('1')); + expect(arrayStack.pop(), isNull); + }); + + test('test case 9: empty stack', () { + ArrayStack arrayStack2 = new ArrayStack(3); + expect(arrayStack2.stack, equals([null, null, null])); + }); +} diff --git a/data_structures/Stack/Linked_List_Stack.dart b/data_structures/Stack/Linked_List_Stack.dart index 6efa5f71..69ac400b 100644 --- a/data_structures/Stack/Linked_List_Stack.dart +++ b/data_structures/Stack/Linked_List_Stack.dart @@ -1,77 +1,85 @@ +import 'package:test/test.dart'; + //Author: Shawn //Email: stepfencurryxiao@gmail.com -class Node{ +class Node { //the data of the Node - T data; - Node next; - - Node(T data){ + T? data; + Node? next; + + Node(T? data) { this.data = data; this.next = null; } } -class LinkedListStack{ +class LinkedListStack { //Top of stack - Node head; - + Node? head; + //Size of stack - int size; - - LinkedListStack(){ + int size = 0; + + LinkedListStack() { this.head = null; this.size = 0; } - + //Add element at top of the stack - - void push(T element){ - Node newNode = new Node(element); - newNode.next = this.head; - this.head = newNode; - this.size++; + + void push(T element) { + Node newNode = new Node(element); + newNode.next = this.head; + this.head = newNode; + this.size++; } - + //Pop element from top at the stack - - T pop(){ - T returnData = null; - if(size == 0){ + + T? pop() { + T? returnData = null; + if (size == 0) { print("The stack is empty!!!"); - } - else{ - Node destroy = this.head; - this.head = this.head.next; - returnData = destroy.data; + } else { + Node? destroy = this.head; + this.head = this.head?.next; + returnData = destroy?.data; this.size--; } return returnData; } - - bool isEmpty(){ + + bool isEmpty() { return this.size == 0; } - - int getSize(){ + + int getSize() { return this.size; } } -int main(){ - LinkedListStack Stack = new LinkedListStack(); - var returnData; - print("Push 2 5 9 7 to the stack\n"); - Stack.push("2"); - Stack.push("5"); - Stack.push("9"); - Stack.push("7"); - print("Successful push!\n"); - returnData = Stack.pop(); - print("Pop a data: $returnData\n"); - returnData = Stack.pop(); - print("Pop a data: $returnData\n"); - returnData = Stack.pop(); - print("Pop a data: $returnData\n"); - return 0; -} \ No newline at end of file +void main() { + test("Push and Pop elements from LinkedListStack", () { + LinkedListStack stack = new LinkedListStack(); + + expect(stack.isEmpty(), isTrue); + expect(stack.getSize(), equals(0)); + + stack.push("2"); + stack.push("5"); + stack.push("9"); + stack.push("7"); + + expect(stack.isEmpty(), isFalse); + expect(stack.getSize(), equals(4)); + + expect(stack.pop(), equals("7")); + expect(stack.pop(), equals("9")); + expect(stack.pop(), equals("5")); + expect(stack.pop(), equals("2")); + + expect(stack.isEmpty(), isTrue); + expect(stack.pop(), isNull); + }); +} diff --git a/data_structures/Stack/balanced_brackets.dart b/data_structures/Stack/balanced_brackets.dart new file mode 100644 index 00000000..f32fb303 --- /dev/null +++ b/data_structures/Stack/balanced_brackets.dart @@ -0,0 +1,55 @@ +import 'package:test/test.dart'; +import 'package:stack/stack.dart'; + +bool isBalancedBrackets(String string) { + Stack stack = Stack(); + + List openingBrackets = ['(', '{', '[']; + final Map matchingBracket = {'}': '{', ')': '(', ']': '['}; + + for (int i = 0; i < string.length; i++) { + var currentChar = string[i]; + + if (openingBrackets.contains(currentChar)) { + stack.push(currentChar); + } else { + if (stack.isNotEmpty) { + if (stack.top() == matchingBracket[currentChar]) { + stack.pop(); + } else { + return false; + } + } else { + return false; + } + } + } + return stack.isEmpty; +} + +void main() { + test(('Balanced Bracket'), () { + expect(isBalancedBrackets('([])(){}(())()()'), isTrue); + }); + + test(('Balanced Bracket'), () { + expect(isBalancedBrackets('()[]{}{'), isFalse); + }); + + test(('Balanced Bracket'), () { + expect(isBalancedBrackets('()()[{()})]'), isFalse); + }); + + test(('Balanced Bracket'), () { + expect(isBalancedBrackets('()([])'), isTrue); + }); + + test(('Balanced Bracket'), () { + expect( + isBalancedBrackets( + '(((((([[[[[[{{{{{{{{{{{{()}}}}}}}}}}}}]]]]]]))))))((([])({})[])[])[]([]){}(())', + ), + isTrue, + ); + }); +} diff --git a/data_structures/binary_tree/basic_binary_tree.dart b/data_structures/binary_tree/basic_binary_tree.dart index 3e03a2c3..7eb5540c 100644 --- a/data_structures/binary_tree/basic_binary_tree.dart +++ b/data_structures/binary_tree/basic_binary_tree.dart @@ -1,38 +1,39 @@ +import 'package:test/test.dart'; + //Author:Shawn //Email:stepfencurryxiao@gmail.com /*This is Class Node with constructor that contains * data variable to type data and left,right pointers */ -class Node{ +class Node { var data; var left; var right; - - Node(var data){ + + Node(var data) { this.data = data; this.left = null; this.right = null; - } + } } /*In order traversal of the tree*/ -void display(var tree){ - - if(tree == null){ +void display(var tree) { + if (tree == null) { return; } - - if(tree.left != null){ + + if (tree.left != null) { display(tree.left); } - + print(tree.data); - - if(tree.right != null){ + + if (tree.right != null) { display(tree.right); } - + return; } @@ -40,55 +41,57 @@ void display(var tree){ *This is the recursive function to find the depth of * binary tree. */ -double depth_of_tree(var tree){ - - if(tree == null){ +double depth_of_tree(var tree) { + if (tree == null) { return 0; - } - else{ + } else { var depth_l_tree = depth_of_tree(tree.left); var depth_r_tree = depth_of_tree(tree.right); - - if(depth_l_tree > depth_r_tree){ + + if (depth_l_tree > depth_r_tree) { return (1 + depth_l_tree); - } - else{ + } else { return (1 + depth_r_tree); } } } /*This function returns that is it full binary tree or not*/ -bool is_full_binary_tree(var tree){ - if(tree == null){ +bool is_full_binary_tree(var tree) { + if (tree == null) { return true; } - if(tree.left == null && tree.right == null){ + if (tree.left == null && tree.right == null) { return true; } - if(tree.left != null && tree.right != null){ + if (tree.left != null && tree.right != null) { return (is_full_binary_tree(tree.left) && is_full_binary_tree(tree.right)); - } - else{ + } else { return false; } } //Main function for testing -void main(){ - var tree = Node(1); - tree.left = Node(2); - tree.right = Node(3); - tree.left.left = Node(4); - tree.left.right = Node(5); - tree.left.right.left = Node(6); - tree.right.left = Node(7); - tree.right.left.left = Node(8); - tree.right.left.left.right = Node(9); - - print(is_full_binary_tree(tree)); - print(depth_of_tree(tree)); - print("Tree is:\n"); - display(tree); -} +void main() { + test("Tree operations", () { + var tree = Node(1); + tree.left = Node(2); + tree.right = Node(3); + tree.left.left = Node(4); + tree.left.right = Node(5); + tree.left.right.left = Node(6); + tree.right.left = Node(7); + tree.right.left.left = Node(8); + tree.right.left.left.right = Node(9); + + expect(is_full_binary_tree(tree), isFalse); + expect(depth_of_tree(tree), equals(5.0)); + }); + test("is_full_binary_tree on full tree", () { + var fullTree = Node(1); + fullTree.left = Node(2); + fullTree.right = Node(3); + expect(is_full_binary_tree(fullTree), isTrue); + }); +} diff --git a/data_structures/binary_tree/binary_tree_traversal.dart b/data_structures/binary_tree/binary_tree_traversal.dart new file mode 100644 index 00000000..2498a86f --- /dev/null +++ b/data_structures/binary_tree/binary_tree_traversal.dart @@ -0,0 +1,139 @@ +import 'dart:collection'; + +import 'package:test/test.dart'; + +class TreeNode { + int? data; + TreeNode? leftNode = null; + TreeNode? rightNode = null; + + int? get value { + return this.data; + } + + TreeNode? get left { + return this.leftNode; + } + + void set left(TreeNode? value) { + this.leftNode = value; + } + + void set right(TreeNode? value) { + this.rightNode = value; + } + + TreeNode? get right { + return this.rightNode; + } + + TreeNode(this.data); +} + +List inOrder(TreeNode? root, List result) { + if (root != null) { + inOrder(root.left, result); + result.add(root.value); + inOrder(root.right, result); + } + return result; +} + +List preOrder(TreeNode? root, List result) { + if (root != null) { + result.add(root.value); + preOrder(root.left, result); + preOrder(root.right, result); + } + return result; +} + +List postOrder(TreeNode? root, List result) { + if (root != null) { + postOrder(root.left, result); + postOrder(root.right, result); + result.add(root.value); + } + return result; +} + +List levelOrder(TreeNode? root, List result) { + Queue q = Queue(); + if (root != null) { + q.add(root); + } + + while (!q.isEmpty) { + TreeNode? curr = q.first; + q.removeFirst(); + result.add(curr?.data); + if (curr?.left != null) { + q.addLast(curr?.left); + } + if (curr?.right != null) { + q.addLast(curr?.right); + } + } + + return result; +} + +void main() { + TreeNode? root = TreeNode(1); + root.left = TreeNode(2); + root.right = TreeNode(3); + root.left?.left = TreeNode(4); + root.left?.right = TreeNode(5); + root.left?.right?.left = TreeNode(6); + root.right?.left = TreeNode(7); + root.right?.left?.left = TreeNode(8); + root.right?.left?.left?.right = TreeNode(9); + + List result; + result = List.empty(growable: true); + + test(('inOrder traversal'), () { + result = List.empty(growable: true); + expect(inOrder(root, result), equals([4, 2, 6, 5, 1, 8, 9, 7, 3])); + }); + + test(('preOrder traversal'), () { + result = List.empty(growable: true); + expect(preOrder(root, result), equals([1, 2, 4, 5, 6, 3, 7, 8, 9])); + }); + + test(('postOrder traversal'), () { + result = List.empty(growable: true); + expect(postOrder(root, result), equals([4, 6, 5, 2, 9, 8, 7, 3, 1])); + }); + + test(('levelOrder traversal'), () { + // https://www.geeksforgeeks.org/level-order-tree-traversal/ + result = List.empty(growable: true); + expect(levelOrder(root, result), equals([1, 2, 3, 4, 5, 7, 6, 8, 9])); + }); + + test(('postOrder traversal'), () { + result = List.empty(growable: true); + root = null; + expect(postOrder(root, result), equals([])); + }); + + test(('inOrder traversal'), () { + result = List.empty(growable: true); + root = null; + expect(inOrder(root, result), equals([])); + }); + + test(('preOrder traversal'), () { + result = List.empty(growable: true); + root = null; + expect(preOrder(root, result), equals([])); + }); + + test(('levelOrder traversal'), () { + result = List.empty(growable: true); + root = null; + expect(levelOrder(root, result), equals([])); + }); +} diff --git a/data_structures/linked_list.dart b/data_structures/linked_list.dart deleted file mode 100644 index 0fd320d0..00000000 --- a/data_structures/linked_list.dart +++ /dev/null @@ -1,118 +0,0 @@ -class Node { - Node next; - T value; - - Node(this.value); - Node.before(this.next, this.value); -} - -class LinkedListIterator extends Iterator { - Node _current; - - @override - bool moveNext() => _current != null; - - @override - T get current { - T currentValue = this._current.value; - - this._current = this._current.next; - - return currentValue; - } - - LinkedListIterator(this._current); -} - -class LinkedList extends Iterable { - int _length = 0; - int get length => this._length; - - Node _head; - - @override - Iterator get iterator => new LinkedListIterator(this._head); - - void remove(T item) { - if (this._head?.value == item) { - this._head = this._head?.next; - this._length--; - } - - if (this._head != null) { - Node current = this._head; - while (current?.next != null) { - if (current.next.value == item) { - current.next = current.next.next; - this._length--; - } - - current = current.next; - } - } - } - - T pop() { - if (this._head != null) { - T value = this._head.value; - this._head = this._head.next; - this._length--; - - return value; - } - - return null; - } - - void push(T item) { - this._head = new Node.before(this._head, item); - this._length++; - } - - void add(T item) { - if (this._head == null) { - this._head = new Node(item); - } else { - Node current = this._head; - while (current?.next != null) { - current = current.next; - } - - current.next = Node(item); - } - this._length++; - } -} - -main(List args) { - LinkedList linkedList = new LinkedList(); - linkedList.add(2); - linkedList.add(4); - linkedList.add(6); - linkedList.add(8); - - print(linkedList.join(", ") + " size=${linkedList.length}"); - linkedList.remove(6); - print(linkedList.join(", ") + " size=${linkedList.length}"); - linkedList.remove(2); - print("5 in linkedList - ${linkedList.contains(5)}"); - print("4 in linkedList - ${linkedList.contains(4)}"); - print(linkedList.join(", ") + " size=${linkedList.length}"); - linkedList.remove(8); - print(linkedList.join(", ") + " size=${linkedList.length}"); - linkedList.remove(4); - print(linkedList.join(", ") + " size=${linkedList.length}"); - - LinkedList stack = new LinkedList(); - stack.push(2); - stack.push(4); - stack.push(6); - - print(stack.join(", ") + " size=${stack.length}"); - stack.pop(); - print(stack.join(", ") + " size=${stack.length}"); - stack.pop(); - stack.pop(); - stack.pop(); - print(stack.join(", ") + " size=${stack.length}"); -} diff --git a/data_structures/linked_list/cycle_in_linked_list.dart b/data_structures/linked_list/cycle_in_linked_list.dart new file mode 100644 index 00000000..4d0d24ec --- /dev/null +++ b/data_structures/linked_list/cycle_in_linked_list.dart @@ -0,0 +1,138 @@ +import 'dart:math'; +import 'package:test/test.dart'; + +class Node { + int value; + Node? next = null; + Node(this.value); + + int get nodeValue { + return this.value; + } + + Node? get nextNode { + return this.next; + } +} + +class LinkedList { + Node? _headNode; + Node? _tailNode; + + Node? get head { + return this._headNode; + } + + Node? get tail { + return this._tailNode; + } + + void insert(Node? newNode) { + if (head == null) { + this._headNode = newNode; + this._tailNode = newNode; + } else { + this._tailNode?.next = newNode; + this._tailNode = this._tailNode?.next; + } + } +} + +Node createNode(int value) { + return Node(value); +} + +Node? findCyclicNode(Node? headNode) { + /// Check : https://en.wikipedia.org/wiki/Cycle_detection + /// we maintain a fast and slow pointer + /// The fast pointer jumps 2 nodes at a time + /// and the slow pointer jumps one node at a time + /// eventually the fast and slow will coincide on a node + /// + /// Then we place one of the node back to the head. + /// The node where these two nodes coincide again will be the + /// origin of the loop node. + /// and move in tandem. check algorith for proof + Node? fastNode = headNode; + Node? slowNode = headNode; + + while (fastNode != null && fastNode.next != null) { + slowNode = slowNode?.next; + fastNode = fastNode.next?.next; + + if (slowNode == fastNode) { + break; + } + } + + if (slowNode == fastNode) { + slowNode = headNode; + while (slowNode != fastNode) { + slowNode = slowNode?.next; + fastNode = fastNode?.next; + } + return slowNode; + } else { + return null; + } +} + +void main() { + LinkedList linkedList = LinkedList(); + List allNodes = []; + for (var i = 0; i <= 10; i++) { + Node newNode = createNode(i); + linkedList.insert(newNode); + allNodes.add(newNode); + } + Node? tail = linkedList.tail; + Random random = new Random(); + + test(('test 1'), () { + int randomIndex = random.nextInt(9); + tail?.next = allNodes[randomIndex]; + Node? cycleNode = findCyclicNode(linkedList.head); + expect(cycleNode, equals(allNodes[randomIndex])); + }); + test(('test 2'), () { + int randomIndex = random.nextInt(9); + tail?.next = allNodes[randomIndex]; + Node? cycleNode = findCyclicNode(linkedList.head); + expect(cycleNode, equals(allNodes[randomIndex])); + }); + + test(('test 3'), () { + int randomIndex = random.nextInt(9); + tail?.next = allNodes[randomIndex]; + Node? cycleNode = findCyclicNode(linkedList.head); + expect(cycleNode, equals(allNodes[randomIndex])); + }); + + test(('test 4'), () { + int randomIndex = random.nextInt(9); + tail?.next = allNodes[randomIndex]; + Node? cycleNode = findCyclicNode(linkedList.head); + expect(cycleNode, equals(allNodes[randomIndex])); + }); + + test(('test 5'), () { + int randomIndex = random.nextInt(9); + tail?.next = allNodes[randomIndex]; + Node? cycleNode = findCyclicNode(linkedList.head); + expect(cycleNode, equals(allNodes[randomIndex])); + }); + + test(('test 6'), () { + int randomIndex = random.nextInt(9); + tail?.next = allNodes[randomIndex]; + Node? cycleNode = findCyclicNode(linkedList.head); + expect(cycleNode, equals(allNodes[randomIndex])); + }); + + test(('test 7'), () { + int randomIndex = random.nextInt(9); + tail?.next = allNodes[randomIndex]; + Node? cycleNode = findCyclicNode(linkedList.head); + expect(cycleNode, equals(allNodes[randomIndex])); + }); +} diff --git a/data_structures/linked_list/linked_list.dart b/data_structures/linked_list/linked_list.dart new file mode 100644 index 00000000..a0eda717 --- /dev/null +++ b/data_structures/linked_list/linked_list.dart @@ -0,0 +1,154 @@ +import 'package:test/test.dart'; + +class Node { + Node? next; + T? value; + + Node(this.value); + Node.before(this.next, this.value); +} + +class LinkedListIterator implements Iterator { + Node? _current; + + @override + bool moveNext() => _current != null; + + @override + T? get current { + T? currentValue = this._current?.value; + + this._current = this._current?.next; + + return currentValue; + } + + LinkedListIterator(this._current); +} + +class LinkedList extends Iterable { + int _length = 0; + int get length => this._length; + + Node? _head; + + @override + Iterator get iterator => new LinkedListIterator(this._head); + + void remove(T? item) { + if (this._head?.value == item) { + this._head = this._head?.next; + this._length--; + } + + if (this._head != null) { + Node? current = this._head; + while (current?.next != null) { + if (current?.next?.value == item) { + current?.next = current.next?.next; + this._length--; + } + + current = current?.next; + } + } + } + + T? pop() { + if (this._head != null) { + T? value = this._head?.value; + this._head = this._head?.next; + this._length--; + + return value; + } + + return null; + } + + void push(T item) { + this._head = new Node.before(this._head, item); + this._length++; + } + + void add(T? item) { + if (this._head == null) { + this._head = new Node(item); + } else { + Node? current = this._head; + while (current?.next != null) { + current = current?.next; + } + + current?.next = Node(item); + } + this._length++; + } +} + +main() { + test(".add is adding elements in order", () { + LinkedList linkedList = new LinkedList(); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + + expect(linkedList, equals([1, 2, 3])); + }); + + test(".remove is removing all elements with given value", () { + LinkedList linkedList = new LinkedList(); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.add(2); + + linkedList.remove(2); + + expect(linkedList, equals([1, 3])); + }); + + test(".remove on empty list do nothing", () { + LinkedList linkedList = new LinkedList(); + + linkedList.remove(2); + + expect(linkedList, isEmpty); + }); + + test(".push is appending first element", () { + LinkedList linkedList = new LinkedList(); + + linkedList.push(1); + expect(linkedList, equals([1])); + + linkedList.push(2); + expect(linkedList, equals([2, 1])); + + linkedList.push(3); + expect(linkedList, equals([3, 2, 1])); + }); + + test(".pop is returning and removing first element", () { + LinkedList linkedList = new LinkedList(); + + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + + expect(linkedList.pop(), equals(1)); + expect(linkedList, equals([2, 3])); + + expect(linkedList.pop(), equals(2)); + expect(linkedList, equals([3])); + + expect(linkedList.pop(), equals(3)); + expect(linkedList, equals([])); + }); + + test(".pop is returning null when list is empty", () { + LinkedList linkedList = new LinkedList(); + + expect(linkedList.pop(), isNull); + }); +} diff --git a/data_structures/linked_list/merge_sorted_list.dart b/data_structures/linked_list/merge_sorted_list.dart new file mode 100644 index 00000000..c31c26c7 --- /dev/null +++ b/data_structures/linked_list/merge_sorted_list.dart @@ -0,0 +1,94 @@ +// https://leetcode.com/problems/merge-two-sorted-lists/ +import 'package:test/test.dart'; + +class ListNode { + int? val; + ListNode? next; + ListNode({this.val = 0, this.next}); +} + +extension PrintLinkedList on ListNode? { + void printLinkedList() { + ListNode? node = this; + while (node != null) { + print(node.val); + node = node.next; + } + } + + List listValues() { + List values = []; + ListNode? node = this; + while (node != null) { + values.add(node.val); + node = node.next; + } + return values; + } +} + +ListNode? mergeTwoLists(ListNode? list1, ListNode? list2) { + if (list1 == null) { + return list2; + } else if (list2 == null) { + return list1; + } + ListNode head = list1; + + if ((list1.val ?? 0) < (list2.val ?? 0)) { + head = list1; + list1 = list1.next; + } else { + head = list2; + list2 = list2.next; + } + + ListNode? node = head; + + while (list1 != null || list2 != null) { + if (list1 != null && list2 != null) { + if ((list1.val ?? 0) < (list2.val ?? 0)) { + node?.next = list1; + list1 = list1.next; + } else { + node?.next = list2; + list2 = list2.next; + } + } else if (list1 != null) { + node?.next = list1; + list1 = list1.next; + } else { + node?.next = list2; + list2 = list2?.next; + } + + node = node?.next; + } + return head; +} + +void main() { + test('test case 1', () { + ListNode head1 = ListNode( + val: 1, + next: ListNode(val: 2, next: ListNode(val: 4)), + ); + ListNode head2 = ListNode( + val: 1, + next: ListNode(val: 3, next: ListNode(val: 4)), + ); + expect(mergeTwoLists(head1, head2).listValues(), [1, 1, 2, 3, 4, 4]); + }); + + test('test case 2', () { + ListNode head1 = ListNode( + val: 1, + next: ListNode(val: 2, next: ListNode(val: 3)), + ); + ListNode head2 = ListNode( + val: 4, + next: ListNode(val: 5, next: ListNode(val: 6)), + ); + expect(mergeTwoLists(head1, head2).listValues(), [1, 2, 3, 4, 5, 6]); + }); +} diff --git a/dynamic_programming/01knapsack_recursive.dart b/dynamic_programming/01knapsack_recursive.dart new file mode 100644 index 00000000..55924098 --- /dev/null +++ b/dynamic_programming/01knapsack_recursive.dart @@ -0,0 +1,50 @@ +import 'dart:math'; +import 'package:test/test.dart'; + +int knapSackProblem( + int capacity, + List values, + List weights, [ + int? numberOfItems, +]) { + numberOfItems ??= values.length; + if (numberOfItems == 0 || capacity == 0) { + return 0; + } + int currentValue = values[numberOfItems - 1]; + int currentWeight = weights[numberOfItems - 1]; + + if (weights[numberOfItems - 1] <= capacity) { + return max( + currentValue + + knapSackProblem( + capacity - currentWeight, + values, + weights, + numberOfItems - 1, + ), + knapSackProblem(capacity, values, weights, numberOfItems - 1), + ); + } else { + return knapSackProblem(capacity, values, weights, numberOfItems - 1); + } +} + +void main() { + int ans = knapSackProblem(10, [1, 4, 5, 6], [2, 3, 6, 7]); + print(ans); + + test('TC: 1', () { + expect(knapSackProblem(10, [1, 4, 5, 6], [2, 3, 6, 7]), 10); + }); + + ans = knapSackProblem(100, [2, 70, 30, 69, 100], [1, 70, 30, 69, 100]); + print(ans); + + test('TC: 2', () { + expect( + knapSackProblem(100, [2, 70, 30, 69, 100], [1, 70, 30, 69, 100]), + 101, + ); + }); +} diff --git a/dynamic_programming/coin_change.dart b/dynamic_programming/coin_change.dart new file mode 100644 index 00000000..f03c64f9 --- /dev/null +++ b/dynamic_programming/coin_change.dart @@ -0,0 +1,41 @@ +import 'dart:math'; +import 'package:test/test.dart'; + +/// we build an array which calculates the min coins for all amounts upto n +/// +/// bottom up approach where we calculate the number of coins used for each +/// amount from 1 to n for each coin. +/// time complexity O(targetAmount * coinDenoms) +/// space complexity O(targetAmount) +int minNumberOfCoins(int targetAmount, List coinDenoms) { + List amounts = new List.generate( + targetAmount + 1, + (int index) => 1000000000000, + ); + + amounts[0] = 0; + + for (int currentCoin in coinDenoms) { + for (int amount = currentCoin; amount <= targetAmount; amount++) { + amounts[amount] = min(amounts[amount], amounts[amount - currentCoin] + 1); + } + } + if (amounts[targetAmount] != 1000000000000) { + return amounts[targetAmount]; + } + return -1; +} + +void main() { + test(('testCase #1'), () { + expect(minNumberOfCoins(7, [1, 5, 10]), equals(3)); + }); + + test(('testCase #2'), () { + expect(minNumberOfCoins(7, [3, 5]), equals(-1)); + }); + + test(('testCase #3'), () { + expect(minNumberOfCoins(9, [3, 4, 5]), equals(2)); + }); +} diff --git a/dynamic_programming/kadanes_algorithm.dart b/dynamic_programming/kadanes_algorithm.dart new file mode 100644 index 00000000..75934623 --- /dev/null +++ b/dynamic_programming/kadanes_algorithm.dart @@ -0,0 +1,43 @@ +import 'package:test/test.dart'; +import 'dart:math'; + +int kadanesAlgorithm(List array) { + int maxEndingHere = array[0]; + int maxSoFar = array[0]; + + for (int num in array.sublist(1, array.length)) { + maxEndingHere = max(maxEndingHere + num, num); + maxSoFar = max(maxSoFar, maxEndingHere); + } + return maxSoFar; +} + +void main() { + List array; + int maxContiniousSubarraySum; + + test(('.Check the response for each test case'), () { + array = [3, 5, -9, 1, 3, -2, 3, 4, 7, 2, -9, 6, 3, 1, -5, 4]; + + maxContiniousSubarraySum = kadanesAlgorithm(array); + expect(maxContiniousSubarraySum, equals(19)); + }); + + test(('.Check the response for each test case'), () { + array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + maxContiniousSubarraySum = kadanesAlgorithm(array); + expect(maxContiniousSubarraySum, equals(55)); + }); + + test(('.Check the response for each test case'), () { + array = [-1, -2, -3, -4, -5, -6, -7, -8, -9, -10]; + maxContiniousSubarraySum = kadanesAlgorithm(array); + expect(maxContiniousSubarraySum, equals(-1)); + }); + + test(('.Check the response for each test case'), () { + array = [1, 2, 3, 4, 5, 6, -22, 7, 8, 9, 10]; + maxContiniousSubarraySum = kadanesAlgorithm(array); + expect(maxContiniousSubarraySum, equals(34)); + }); +} diff --git a/dynamic_programming/longest_common_subsequence.dart b/dynamic_programming/longest_common_subsequence.dart new file mode 100644 index 00000000..8f6ed250 --- /dev/null +++ b/dynamic_programming/longest_common_subsequence.dart @@ -0,0 +1,56 @@ +// Longest Common Subsequence Editorial: https://www.geeksforgeeks.org/longest-common-subsequence-dp-4/ +//Longest Common Subsequence Wiki: https://en.wikipedia.org/wiki/Longest_common_subsequence_problem +import 'dart:math'; +import 'package:test/test.dart'; + +int longestCommonSubsequence(String text1, String text2) { + int m = text1.length; + int n = text2.length; + + // BottomUp Tabulation + List> dp = List.generate(m + 1, (_) => List.filled(n + 1, 0)); + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + if (text1[i - 1] == text2[j - 1]) { + dp[i][j] = 1 + dp[i - 1][j - 1]; + continue; + } + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); + } + } + return dp[m][n]; +} + +void main() { + test(('testCase #1'), () { + expect(longestCommonSubsequence("", ""), equals(0)); + }); + + test(('testCase #2'), () { + expect(longestCommonSubsequence("", "abcd"), equals(0)); + }); + test(('testCase #3'), () { + expect(longestCommonSubsequence("abcd", ""), equals(0)); + }); + test(('testCase #4'), () { + expect(longestCommonSubsequence("abcd", "c"), equals(1)); + }); + test(('testCase #5'), () { + expect(longestCommonSubsequence("abcd", "d"), equals(1)); + }); + test(('testCase #6'), () { + expect(longestCommonSubsequence("abcd", "e"), equals(0)); + }); + test(('testCase #7'), () { + expect(longestCommonSubsequence("abcdefghi", "acegi"), equals(5)); + }); + test(('testCase #8'), () { + expect(longestCommonSubsequence("abcdgh", "aedfhr"), equals(3)); + }); + test(('testCase #9'), () { + expect(longestCommonSubsequence("aggtab", "gxtxayb"), equals(4)); + }); + test(('testCase #10'), () { + expect(longestCommonSubsequence("ggg", "g"), equals(1)); + }); +} diff --git a/dynamic_programming/longest_common_substring.dart b/dynamic_programming/longest_common_substring.dart new file mode 100644 index 00000000..46918727 --- /dev/null +++ b/dynamic_programming/longest_common_substring.dart @@ -0,0 +1,63 @@ +// Longest Common Substring Editorial: https://www.geeksforgeeks.org/longest-common-substring-dp-29/ +//Longest Common Substring Wiki: https://en.wikipedia.org/wiki/Longest_common_substring_problem + +import 'dart:math'; +import 'package:test/test.dart'; + +int longestCommonSubstring(String text1, String text2) { + int m = text1.length; + int n = text2.length; + + // BottomUp Tabulation + List> dp = List.generate(m + 1, (_) => List.filled(n + 1, 0)); + int ans = 0; + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + if (text1[i - 1] == text2[j - 1]) { + dp[i][j] = 1 + dp[i - 1][j - 1]; + ans = max(ans, dp[i][j]); + } + } + } + return ans; +} + +void main() { + test(('testCase #1'), () { + expect(longestCommonSubstring("", ""), equals(0)); + }); + + test(('testCase #2'), () { + expect(longestCommonSubstring("a", ""), equals(0)); + }); + test(('testCase #3'), () { + expect(longestCommonSubstring("", "a"), equals(0)); + }); + test(('testCase #4'), () { + expect(longestCommonSubstring("c", "c"), equals(1)); + }); + test(('testCase #5'), () { + expect(longestCommonSubstring("abcdef", "bcd"), equals(3)); + }); + test(('testCase #6'), () { + expect(longestCommonSubstring("abcdef", "xabded"), equals(2)); + }); + test(('testCase #7'), () { + expect(longestCommonSubstring("GeeksforGeeks", "GeeksQuiz"), equals(5)); + }); + test(('testCase #8'), () { + expect(longestCommonSubstring("abcdxyz", "xyzabcd"), equals(4)); + }); + test(('testCase #9'), () { + expect(longestCommonSubstring("zxabcdezy", "yzabcdezx"), equals(6)); + }); + test(('testCase #10'), () { + expect( + longestCommonSubstring( + "OldSite:GeeksforGeeks.org", + "NewSite:GeeksQuiz.com", + ), + equals(10), + ); + }); +} diff --git a/dynamic_programming/min_number_of_jumps.dart b/dynamic_programming/min_number_of_jumps.dart new file mode 100644 index 00000000..117dadee --- /dev/null +++ b/dynamic_programming/min_number_of_jumps.dart @@ -0,0 +1,44 @@ +import 'dart:math'; +import 'package:test/test.dart'; + +int minimumNumberOfJumps(List array) { + List jumps = List.generate((array.length), (index) => 1000000000000); + jumps[0] = 0; + int length = array.length; + for (int i = 1; i < length; i++) { + for (int j = 0; j < i; j++) { + if (array[j] + j >= i) { + jumps[i] = min(jumps[j] + 1, jumps[i]); + } + } + } + return jumps[length - 1]; +} + +void main() { + List array; + test('test 1', () { + array = [3, 4, 2, 1, 2, 3, 7, 1, 1, 1, 3]; + expect(minimumNumberOfJumps(array), 4); + }); + test('test 2', () { + array = [1]; + expect(minimumNumberOfJumps(array), 0); + }); + test('test 3', () { + array = [1, 1]; + expect(minimumNumberOfJumps(array), 1); + }); + test('test 4', () { + array = [1, 1, 1]; + expect(minimumNumberOfJumps(array), 2); + }); + test('test 5', () { + array = [2, 1, 2, 3, 1, 1, 1]; + expect(minimumNumberOfJumps(array), 3); + }); + test('test 6', () { + array = [3, 4, 2, 1, 2, 3, 7, 1, 1, 1, 3, 2, 3, 2, 1, 1, 1, 1]; + expect(minimumNumberOfJumps(array), 7); + }); +} diff --git a/graphs/area_of_island.dart b/graphs/area_of_island.dart new file mode 100644 index 00000000..688dc037 --- /dev/null +++ b/graphs/area_of_island.dart @@ -0,0 +1,127 @@ +import 'package:test/test.dart'; + +extension MinMax on List { + int get max { + num maxNumber = double.negativeInfinity; + for (int i = 0; i < length; ++i) { + if (maxNumber < this[i]) { + maxNumber = this[i]; + } + } + if (maxNumber != double.negativeInfinity) { + return maxNumber.toInt(); + } + return 0; + } +} + +const List> deltas = [ + [-1, 0], // top neighbour + [0, 1], // right neighbour + [1, 0], // bottom neighbour + [0, -1], // left neighbour. +]; + +int maxAreaOfIsland(List> grid) { + int numRows = grid.length; + int numCols = grid[0].length; + List> visited = List.generate( + numRows, + (int index) => List.filled(numCols, false), + ); + + List areas = []; + for (int i = 0; i < numRows; ++i) { + for (int j = 0; j < numCols; ++j) { + if (visited[i][j] || grid[i][j] == 0) continue; + traverseNode(i, j, grid, visited, areas); + } + } + return areas.max; +} + +bool isInvalidIndex(int i, int j, int rowCount, int colCount) { + return (i < 0 || i >= rowCount || j >= colCount || j < 0); +} + +List> adjacentNodes( + List> grid, + List> visited, + int x, + int y, +) { + List> nodes = []; + for (int i = 0; i < deltas.length; ++i) { + int dx = x + deltas[i][0]; + int dy = y + deltas[i][1]; + + if (isInvalidIndex(dx, dy, grid.length, grid[0].length)) continue; + if (visited[dx][dy] || grid[dx][dy] == 0) continue; + + nodes.add([dx, dy]); + } + return nodes; +} + +void traverseNode( + int i, + int j, + List> grid, + List> visited, + List areas, +) { + int area = 0; + List> nodesToExplore = [ + [i, j], + ]; + while (nodesToExplore.isNotEmpty) { + List node = nodesToExplore.removeLast(); + + int x = node[0]; + int y = node[1]; + + if (visited[x][y]) continue; + visited[x][y] = true; + if (grid[x][y] == 0) continue; + + area += 1; + nodesToExplore.addAll(adjacentNodes(grid, visited, x, y)); + } + if (area > 0) { + areas.add(area); + } +} + +void main() { + test('test case 1', () { + List> island = [ + [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], + [0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0], + [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], + ]; + expect(maxAreaOfIsland(island), 6); + }); + + test('test case 2', () { + List> island = [ + [0, 0, 1], + [0, 0, 0], + [0, 1, 1], + ]; + expect(maxAreaOfIsland(island), 2); + }); + + test('test case 3', () { + List> island = [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + ]; + expect(maxAreaOfIsland(island), 0); + }); +} diff --git a/graphs/breadth_first_search.dart b/graphs/breadth_first_search.dart new file mode 100644 index 00000000..ff504d0d --- /dev/null +++ b/graphs/breadth_first_search.dart @@ -0,0 +1,107 @@ +import 'dart:collection'; +import 'package:test/test.dart'; + +/// Implementation of Breadth First Search +/// https://en.wikipedia.org/wiki/Breadth-first_search + +class Graph { + /// Adjacency List representation using dynamic list and HashMap + HashMap graph = new HashMap>(); + List nodes; + + void makeGraph() { + /// initialise all nodes with empty lists. + /// each node will have a list as value which stores + /// the nodes to which it is connected to + for (int i = 0; i < this.nodes.length; i++) { + this.graph[nodes[i]] = []; + } + } + + Graph(this.nodes) { + this.makeGraph(); + } + + int get numberOfNodesInGraph { + return this.nodes.length; + } + + HashMap get graphDataStructure { + return this.graph; + } + + void addNodes(int newNode) { + this.nodes.add(newNode); + this.graph[newNode] = []; + } + + void addEdges(int start, int end) { + this.graph[start].add(end); + } +} + +List breadthFirstSearch(Graph graph, int numberOfNodes, int startNode) { + Queue queue = new Queue(); + List answer = []; + queue.add(startNode); + while (queue.isNotEmpty) { + int node = queue.removeFirst(); + answer.add(node); + for (int child in graph.graph[node]) { + queue.add(child); + } + } + return answer; +} + +void main() { + test(('Test case 1:'), () { + List nodes = [0, 1, 2]; + int numberOfEdges = 2; + + List> edges = [ + [0, 1], + [0, 2], + ]; + Graph graph = Graph(nodes); + + for (int i = 0; i < numberOfEdges; i++) { + int start = edges[i][0]; + int end = edges[i][1]; + graph.addEdges(start, end); + } + int startNode = 0; + List answer = breadthFirstSearch( + graph, + graph.numberOfNodesInGraph, + startNode, + ); + expect(answer, equals([0, 1, 2])); + }); + + test(('Test case 2:'), () { + List nodes = [0, 1, 2, 3, 4]; + int numberOfEdges = 4; + + List> edges = [ + [0, 1], + [0, 2], + [0, 3], + [2, 4], + ]; + Graph graph = Graph(nodes); + + for (int i = 0; i < numberOfEdges; i++) { + int start = edges[i][0]; + int end = edges[i][1]; + graph.addEdges(start, end); + } + int startNode = 0; + List answer = breadthFirstSearch( + graph, + graph.numberOfNodesInGraph, + startNode, + ); + expect(answer, equals([0, 1, 2, 3, 4])); + }); +} diff --git a/graphs/depth_first_search.dart b/graphs/depth_first_search.dart new file mode 100644 index 00000000..4903e584 --- /dev/null +++ b/graphs/depth_first_search.dart @@ -0,0 +1,120 @@ +import 'dart:collection'; +import 'package:test/test.dart'; + +/// Implementation of Depth First Search +/// https://en.wikipedia.org/wiki/Depth-first_search + +class Graph { + /// Adjacency List representation using dynamic list and HashMap + HashMap graph = new HashMap>(); + List nodes; + + void makeGraph() { + /// initialise all nodes with empty lists. + /// each node will have a list as value which stores + /// the nodes to which it is connected to + for (int i = 0; i < this.nodes.length; i++) { + this.graph[nodes[i]] = []; + } + } + + Graph(this.nodes) { + this.makeGraph(); + } + + int get numberOfNodesInGraph { + return this.nodes.length; + } + + HashMap get graphDataStructure { + return this.graph; + } + + void addNodes(int newNode) { + this.nodes.add(newNode); + this.graph[newNode] = []; + } + + void addEdges(int start, int end) { + this.graph[start].add(end); + } +} + +void depthFirstSearchHelper(graph, visitedNodes, node, answer) { + if (visitedNodes[node]) { + return null; + } + visitedNodes[node] = true; + answer.add(node); + if (graph.containsKey(node)) { + for (int child in graph[node]) { + if (!visitedNodes[child]) { + depthFirstSearchHelper(graph, visitedNodes, child, answer); + } + } + } +} + +List depthFirstSearch(Graph graph, int numberOfNodes, int startNode) { + List visitedNodes = new List.generate( + numberOfNodes, + (index) => false, + ); + + List answer = []; + depthFirstSearchHelper(graph.graph, visitedNodes, startNode, answer); + return answer; +} + +void main() { + test(('Test case 1:'), () { + List nodes = [0, 1, 2, 3]; + int numberOfEdges = 3; + + List> edges = [ + [0, 1], + [1, 2], + [0, 3], + ]; + Graph graph = Graph(nodes); + + for (int i = 0; i < numberOfEdges; i++) { + int start = edges[i][0]; + int end = edges[i][1]; + graph.addEdges(start, end); + } + int startNode = 0; + List answer = depthFirstSearch( + graph, + graph.numberOfNodesInGraph, + startNode, + ); + expect(answer, equals([0, 1, 2, 3])); + }); + + test(('Test case 2:'), () { + List nodes = [0, 1, 2, 3, 4]; + int numberOfEdges = 4; + + List> edges = [ + [0, 1], + [0, 2], + [0, 3], + [2, 4], + ]; + Graph graph = Graph(nodes); + + for (int i = 0; i < numberOfEdges; i++) { + int start = edges[i][0]; + int end = edges[i][1]; + graph.addEdges(start, end); + } + int startNode = 0; + List answer = depthFirstSearch( + graph, + graph.numberOfNodesInGraph, + startNode, + ); + expect(answer, equals([0, 1, 2, 4, 3])); + }); +} diff --git a/graphs/nearest_neighbour_algorithm.dart b/graphs/nearest_neighbour_algorithm.dart index c4675f73..50dc2dcd 100644 --- a/graphs/nearest_neighbour_algorithm.dart +++ b/graphs/nearest_neighbour_algorithm.dart @@ -18,8 +18,8 @@ List nearestNeighbourSearch(Graph graph) { int currentNode = 0; while (unvisitedNodes.isNotEmpty) { unvisitedNodes.remove(currentNode); - int nearestNeighbour; - double nearestNeighbourDistance; + int? nearestNeighbour; + double nearestNeighbourDistance = 0; for (int neighbour in unvisitedNodes) { double neighbourDistance = graph.adjacencyMatrix[currentNode][neighbour]; @@ -31,7 +31,7 @@ List nearestNeighbourSearch(Graph graph) { } path.add(graph.nodes[currentNode]); - currentNode = nearestNeighbour; + currentNode = nearestNeighbour ?? 0; } return path; @@ -71,19 +71,16 @@ Graph fromPoints(List points) { } void main() { - Graph graph = Graph([ - "A", - "B", - "C", - "D", - "E" - ], [ - [0, 12, 4, 54, 100], - [3, 0, 5, 1, 1], - [300, 20, 0, 433, 123], - [32, 31, 54, 0, 3], - [2, 65, 12, 32, 0] - ]); + Graph graph = Graph( + ["A", "B", "C", "D", "E"], + [ + [0, 12, 4, 54, 100], + [3, 0, 5, 1, 1], + [300, 20, 0, 433, 123], + [32, 31, 54, 0, 3], + [2, 65, 12, 32, 0], + ], + ); print(nearestNeighbourSearch(graph)); @@ -94,7 +91,7 @@ void main() { new Point(3.33, 8.11), new Point(12, 11), new Point(-1, 1), - new Point(-2, 2) + new Point(-2, 2), ]; print(nearestNeighbourSearch(fromPoints(points))); diff --git a/maths/Armstrong_number.dart b/maths/Armstrong_number.dart new file mode 100644 index 00000000..b53c4bdf --- /dev/null +++ b/maths/Armstrong_number.dart @@ -0,0 +1,24 @@ +import 'dart:math'; + +bool Armstrong_no(var x) { + var n = x; + var s = n.toString(); + var d = s.length; + var sum = 0; + while (n != 0) { + var r = n % 10; + sum = sum + pow(r, d).toInt(); + n = n ~/ 10; + } + return sum == x; +} + +void main() { + for (var x in [0, 10, 370, 371]) { + if (Armstrong_no(x)) { + print("${x} is armstrong number"); + } else { + print("${x} is not Armstrong number"); + } + } +} diff --git a/maths/Kynea_numbers.dart b/maths/Kynea_numbers.dart new file mode 100644 index 00000000..4e54ba35 --- /dev/null +++ b/maths/Kynea_numbers.dart @@ -0,0 +1,39 @@ +import 'package:test/test.dart'; + +// Function to calculate nth kynea number +int nthKyneaNumber(int n) { + // Calculate nth kynea number + // using formula ((2^n + 1)^2 ) -2 + + // Firstly calculate 2^n + 1 + n = (1 << n) + 1; + + // Now calculate (2^n + 1)^2 + n = n * n; + + // Now calculate ((2^n + 1)^2 ) - 2 + n = n - 2; + + // return nth Kynea number + return n; +} + +// Driver Program + +void main() { + test("1th Kynea number equals to 7", () { + expect(nthKyneaNumber(1), equals(7)); + }); + + test("4th Kynea number equals to 287", () { + expect(nthKyneaNumber(4), equals(287)); + }); + + test("6th Kynea number equals to 4223", () { + expect(nthKyneaNumber(6), equals(4223)); + }); + + test("10th Kynea number equals to 1050623", () { + expect(nthKyneaNumber(10), equals(1050623)); + }); +} diff --git a/maths/LinearDiophantineEqn.dart b/maths/LinearDiophantineEqn.dart new file mode 100644 index 00000000..4a2ad996 --- /dev/null +++ b/maths/LinearDiophantineEqn.dart @@ -0,0 +1,29 @@ +// Program Linear Diophantine equation + +//Find the GCD of two numbers +int gcd(int a, int b) { + return (a % b == 0) ? b.abs() : gcd(b, a % b); +} + +// This function checks if integral solutions are possible +bool Isposs(int a, int b, int c) { + return (c % gcd(a, b) == 0); +} + +//Driver function for Linear Diophantine Equations +int main() { + int a = 3, b = 6, c = 9; + if (Isposs(a, b, c) == true) { + print("Possible"); + } else { + print("Not Possible"); + } + int x = 3, y = 6, z = 8; + if (Isposs(x, y, z) == true) { + print("Possible"); + } else { + print("Not Possible"); + } + + return 0; +} diff --git a/maths/Pow.dart b/maths/Pow.dart deleted file mode 100644 index 9d0d2d64..00000000 --- a/maths/Pow.dart +++ /dev/null @@ -1,14 +0,0 @@ -void main(){ - print(pow(10,2)); // 100 - print(pow(2,0)); // 1 - print(pow(2,10)); // 1024 -} - - -double pow(int a,int b){ - double result = 1; - for(int i = 1;i <= b;i++){ - result *= a; - } - return result; -} diff --git a/maths/Ugly_numbers.dart b/maths/Ugly_numbers.dart new file mode 100644 index 00000000..03f17ab8 --- /dev/null +++ b/maths/Ugly_numbers.dart @@ -0,0 +1,52 @@ +import 'package:test/test.dart'; + +int maxDivide(int a, int b) { + var n; + while (a % b == 0) { + n = a / b; + a = n.toInt(); + } + return a; +} + +/* Function to check if a number is ugly or not */ +bool isUgly(int no) { + no = maxDivide(no, 2); + no = maxDivide(no, 3); + no = maxDivide(no, 5); + + return no == 1; +} + +/* Function to get the nth ugly number*/ +int getNthUglyNo(int n) { + int i = 1; + int count = 1; /* ugly number count */ + + /*Check for all integers untill ugly count + becomes n*/ + while (n > count) { + i++; + if (isUgly(i)) count++; + } + return i; +} + +/* Driver program to test above functions */ +void main() { + test("getNthUglyNo(150) returns 5832", () { + expect(getNthUglyNo(150), equals(5832)); + }); + + test("isUgly returns true for 6", () { + expect(isUgly(6), isTrue); + }); + + test("isUgly returns true for 5832", () { + expect(isUgly(5832), isTrue); + }); + + test("isUgly returns false for 5833", () { + expect(isUgly(5833), isFalse); + }); +} diff --git a/maths/amicable_numbers.dart b/maths/amicable_numbers.dart new file mode 100644 index 00000000..c2cb92bb --- /dev/null +++ b/maths/amicable_numbers.dart @@ -0,0 +1,30 @@ +/* + * https://en.wikipedia.org/wiki/Amicable_numbers + * + *Amicable numbers are two different numbers related in such a way that the sum of the proper divisors of each is equal to the other number. + * + * */ + +//this function returns true if numbers are amicable and false otherwise +bool amicable_number(int first_number, int second_number) { + if (first_number <= 1 || second_number <= 1) return false; + List first_number_proper_divisors = []; + List second_number_proper_divisors = []; + for (int i = 1; i < first_number; i++) { + if (first_number % i == 0) first_number_proper_divisors.add(i); + } + for (int i = 1; i < second_number; i++) { + if (second_number % i == 0) second_number_proper_divisors.add(i); + } + return first_number == + second_number_proper_divisors.reduce((a, b) => a + b) && + second_number == first_number_proper_divisors.reduce((a, b) => a + b); +} + +void main() { + print(amicable_number(12, 14)); // false + print(amicable_number(220, 284)); // true + print(amicable_number(60, 84)); // true + print(amicable_number(1184, 1210)); //true + print(amicable_number(-14, 10)); //false +} diff --git a/maths/average.dart b/maths/average.dart index d195e39a..32cee4f0 100644 --- a/maths/average.dart +++ b/maths/average.dart @@ -1,7 +1,7 @@ //Find mean of a list of numbers. -average(List numbers) { - var sum = 0; +average(List numbers) { + int sum = 0; for (var x in numbers) { sum += x; } diff --git a/maths/eulers_totient.dart b/maths/eulers_totient.dart new file mode 100644 index 00000000..9d3e7b54 --- /dev/null +++ b/maths/eulers_totient.dart @@ -0,0 +1,38 @@ +/* Source: + * https://en.wikipedia.org/wiki/Euler%27s_totient_function + * + * Description: + * eulers_totient(n) = n * product(1 - 1/p for all prime p dividing n) + * + * Time Complexity: + * O(sqrt(n)) + */ + +int eulers_totient(int n) { + // Input: n: int + // Output: phi(n): count of numbers b/w 1 and n that are coprime to n + int res = n; + for (int i = 2; i * i <= n; i++) { + if (n % i == 0) { + while (n % i == 0) { + n = n ~/ i; + } + // i is a prime dividing n, multiply res bu 1 - 1/i + // res = res * (1 - 1/i) = res - (res/i) + res = res - (res ~/ i); + } + } + if (n > 1) { + res = res - (res ~/ n); + } + return res; +} + +main() { + // eulers_totient(9) = 6 as 1, 2, 4, 5, 6, 7, 8 are coprime to 9 + // > 6 + print(eulers_totient(9)); + // eulers_totient(10) = 4 as 1, 3, 7, 9 are coprime to 10 + // > 4 + print(eulers_totient(10)); +} diff --git a/maths/factorial_approximation.dart b/maths/factorial_approximation.dart index 71f8790e..821dd655 100644 --- a/maths/factorial_approximation.dart +++ b/maths/factorial_approximation.dart @@ -7,7 +7,7 @@ double factorial(double x) { pow(8 * pow(x, 3) + 4 * pow(x, 2) + x + 1 / 30, 1 / 6); } -main(List args) { +main() { for (int i = 0; i < 10; i++) { print("$i! ~= ${factorial(i.toDouble())}"); } diff --git a/maths/factorial_recursion.dart b/maths/factorial_recursion.dart index d1f3f8f9..d620fcaa 100644 --- a/maths/factorial_recursion.dart +++ b/maths/factorial_recursion.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - void main() { var n = 5; var fac = factorial(n); diff --git a/maths/factors.dart b/maths/factors.dart new file mode 100644 index 00000000..5538449d --- /dev/null +++ b/maths/factors.dart @@ -0,0 +1,21 @@ +void main() { + print("factors: ${factorsOf(12)}"); //factors: [1, 2, 3, 4, 6, 12] + + try { + print( + factorsOf(-1).toString(), + ); //Unhandled exception: Exception: A non-positive value was passed to the function + } catch (ex) { + print(ex); + } +} + +List factorsOf(int num) { + if (num <= 0) + throw Exception("A non-positive value was passed to the function"); + List factors = [1]; + for (int i = 2; i <= num; i++) { + if (num % i == 0) factors.add(i); + } + return factors; +} diff --git a/maths/fermats_little_theorem.dart b/maths/fermats_little_theorem.dart index 9f4378a7..4d3847eb 100644 --- a/maths/fermats_little_theorem.dart +++ b/maths/fermats_little_theorem.dart @@ -1,3 +1,6 @@ +@Skip('currently failing (see issue #86)') +import 'package:test/test.dart'; + /* Fermat's little Theorem Translated from TheAlgorithms/Python diff --git a/maths/fibonacci_dynamic_programming.dart b/maths/fibonacci_dynamic_programming.dart new file mode 100644 index 00000000..973ab618 --- /dev/null +++ b/maths/fibonacci_dynamic_programming.dart @@ -0,0 +1,37 @@ +import 'package:test/test.dart'; + +//Title: Nth Fibonacci Number using Dynamic Programming +//Author: Richik Chanda +//Email: richikchanda1999@gmail.com +List dp = []; +int mod = (1e9 + 7).toInt(); + +//Get the nth Fibonacci number modulo 10^9 + 7 since it can be a very large number +int getFib(int n) { + if (dp[n] == -1) dp[n] = (getFib(n - 1) % mod) + (getFib(n - 2) % mod); + return dp[n] % mod; +} + +//Driver +void main() { + dp = List.generate((1e6 + 1).toInt(), (e) => -1); + dp[0] = 0; + dp[1] = 1; + + test("getFib 0 equals 0", () { + expect(getFib(0), equals(0)); + }); + + test("getFib 1 equals 1", () { + expect(getFib(1), equals(1)); + }); + + test("getFib 5 equals 5", () { + expect(getFib(5), equals(5)); + }); + + test("getFib(n) equals getFib(n - 1) + getFib(n - 2)", () { + expect(getFib(7), equals(getFib(6) + getFib(5))); + expect(getFib(14), equals(getFib(13) + getFib(12))); + }); +} diff --git a/maths/find_max_recursion.dart b/maths/find_max_recursion.dart index d9565953..5a20f6e0 100644 --- a/maths/find_max_recursion.dart +++ b/maths/find_max_recursion.dart @@ -12,9 +12,15 @@ int find_max_recursion(List numbers, int low, int high) { return numbers[low]; // or numbers[high] } int mid = (low + high) >> 1; - int leftMax = - find_max_recursion(numbers, low, mid); /* max in range [low mid] */ + int leftMax = find_max_recursion( + numbers, + low, + mid, + ); /* max in range [low mid] */ int rightMax = find_max_recursion( - numbers, mid + 1, high); /* max in range [mid + 1, high] */ + numbers, + mid + 1, + high, + ); /* max in range [mid + 1, high] */ return leftMax >= rightMax ? leftMax : rightMax; } diff --git a/maths/find_min_recursion.dart b/maths/find_min_recursion.dart index b53ca13e..0c4b7be1 100644 --- a/maths/find_min_recursion.dart +++ b/maths/find_min_recursion.dart @@ -12,9 +12,15 @@ int find_min_recursion(List numbers, int low, int high) { return numbers[low]; // or numbers[high] } int mid = (low + high) >> 1; - int leftMin = - find_min_recursion(numbers, low, mid); /* min in range [low mid] */ + int leftMin = find_min_recursion( + numbers, + low, + mid, + ); /* min in range [low mid] */ int rightMin = find_min_recursion( - numbers, mid + 1, high); /* min in range [mid + 1, high] */ + numbers, + mid + 1, + high, + ); /* min in range [mid + 1, high] */ return leftMin <= rightMin ? leftMin : rightMin; } diff --git a/maths/hamming_distance.dart b/maths/hamming_distance.dart index 6fdf4fd8..74fba95a 100644 --- a/maths/hamming_distance.dart +++ b/maths/hamming_distance.dart @@ -9,7 +9,7 @@ int hamming_distance(String stringA, String stringB) { //strings must be of equal length if (stringA.length != stringB.length) { print('String lengths must be same!'); - return null; + return 0; } else { distance = 0; for (var i = 0; i < stringA.length; i++) { @@ -22,9 +22,9 @@ int hamming_distance(String stringA, String stringB) { } void main() { - var stringA; - var stringB; - var dist; + String stringA; + String stringB; + int dist; stringA = 'karolin'; stringB = 'kathrin'; diff --git a/maths/lu_decomposition.dart b/maths/lu_decomposition.dart index 857a8cc6..d0350a7e 100644 --- a/maths/lu_decomposition.dart +++ b/maths/lu_decomposition.dart @@ -20,19 +20,19 @@ class LUPDecomposition { } class Matrix { - List> _values; + List> values; @override - String toString() => this._values.toString(); + String toString() => this.values.toString(); - int get nRows => this._values.length; - int get nColumns => this.nRows == 0 ? 0 : this._values[0].length; + int get nRows => this.values.length; + int get nColumns => this.nRows == 0 ? 0 : this.values[0].length; bool get isSquare => this.nRows == this.nColumns; - List> get rows => this._values; + List> get rows => this.values; - List operator [](int n) => this._values[n]; + List operator [](int n) => this.values[n]; Matrix operator +(Matrix other) { if (this.nRows != other.nRows || this.nColumns != other.nColumns) { @@ -48,7 +48,7 @@ class Matrix { values.add(newRow); } - return new Matrix(values); + return new Matrix(values: values); } Matrix operator -(Matrix other) { @@ -66,7 +66,7 @@ class Matrix { values.add(newRow); } - return new Matrix(values); + return new Matrix(values: values); } Matrix times(double n) { @@ -99,7 +99,7 @@ class Matrix { values.add(newRow); } - return new Matrix(values); + return new Matrix(values: values); } LUPDecomposition decompose() { @@ -203,33 +203,33 @@ class Matrix { } } - Matrix.eye(int size) { - this._values = []; + Matrix.eye(int size, {this.values = const []}) { + this.values = []; for (int i = 0; i < size; i++) { List row = List.generate(size, (x) => 0); row[i] = 0; - this._values.add(row); + this.values.add(row); } } - Matrix.from(Matrix matrix) { - this._values = matrix.rows.map((row) => List.from(row)).toList(); + Matrix.from(Matrix matrix, {this.values = const []}) { + this.values = matrix.rows.map((row) => List.from(row)).toList(); } - Matrix.zeros(int nRows, int nColumns) { - this._values = []; + Matrix.zeros(int nRows, int nColumns, {this.values = const []}) { + this.values = []; for (int i = 0; i < nRows; i++) { List row = []; for (int j = 0; j < nColumns; j++) { row.add(0); } - this._values.add(row); + this.values.add(row); } } - Matrix(List> values) { + Matrix({List> this.values = const []}) { if (values.length != 0) { int rowLength = values[0].length; if (values.any((row) => row.length != rowLength)) { @@ -237,7 +237,7 @@ class Matrix { } } - this._values = values; + this.values = values; } } @@ -280,11 +280,13 @@ double f(double x, double y) { } void main() { - Matrix a = new Matrix([ - [3, 2, -1], - [2, -2, 4], - [-1, 0.5, -1] - ]); + Matrix a = new Matrix( + values: [ + [3, 2, -1], + [2, -2, 4], + [-1, 0.5, -1], + ], + ); List b = [1, -2, 0]; List solution = solve(a, b); diff --git a/maths/newton_method.dart b/maths/newton_method.dart index 49d6418d..4862181a 100644 --- a/maths/newton_method.dart +++ b/maths/newton_method.dart @@ -6,8 +6,12 @@ double derivative(double Function(double) f, double x, [double h = 1e-10]) { } /// Find root of given [f] (x where [f(x)] == 0) -double findRoot(double Function(double) f, - [double initialValue = 0, int iterations = 10, double h = 1e-10]) { +double findRoot( + double Function(double) f, [ + double initialValue = 0, + int iterations = 10, + double h = 1e-10, +]) { double currentValue = initialValue; for (int i = 0; i < iterations; i++) { currentValue -= f(currentValue) / derivative(f, currentValue); diff --git a/maths/perfect_number.dart b/maths/perfect_number.dart new file mode 100644 index 00000000..f6a5519f --- /dev/null +++ b/maths/perfect_number.dart @@ -0,0 +1,28 @@ +/* + * From: https://www.britannica.com/science/perfect-number + * + * A positive integer that is equal to the sum of its proper divisors. + * The smallest perfect number is 6, which is the sum of 1, 2, and 3. + * Other perfect numbers are 28, 496, and 8,128. + * + * */ + +//this function returns true if number is perfect and false otherwise +bool perfect_number(int number) { + if (number <= 1) return false; + List divisors = []; + for (int i = 1; i < number; i++) { + if (number % i == 0) divisors.add(i); + } + return divisors.reduce((a, b) => a + b) == number; +} + +void main() { + print(perfect_number(-1)); // false + print(perfect_number(6)); // true + print(perfect_number(12)); // false + print(perfect_number(16)); // false + print(perfect_number(26)); // false + print(perfect_number(27)); // false + print(perfect_number(28)); // true +} diff --git a/maths/pow.dart b/maths/pow.dart new file mode 100644 index 00000000..390c3ee8 --- /dev/null +++ b/maths/pow.dart @@ -0,0 +1,13 @@ +void main() { + print(pow(10, 2)); // 100 + print(pow(2, 0)); // 1 + print(pow(2, 10)); // 1024 +} + +double pow(int a, int b) { + double result = 1; + for (int i = 1; i <= b; i++) { + result *= a; + } + return result; +} diff --git a/maths/power_of_two.dart b/maths/power_of_two.dart new file mode 100644 index 00000000..cd8f485e --- /dev/null +++ b/maths/power_of_two.dart @@ -0,0 +1,41 @@ +import 'package:test/test.dart'; + +bool power_of_two(int n) { + if (n == 0) return false; + + return (n & (n - 1)) == 0; +} + +void main() { + test("Test power_of_two 0 returns false", () { + expect(power_of_two(0), isFalse); + }); + + test("Test power_of_two 1 returns true", () { + expect(power_of_two(1), isTrue); + }); + + test("Test power_of_two 10 returns false", () { + expect(power_of_two(10), isFalse); + }); + + test("Test power_of_two 10 returns false", () { + expect(power_of_two(10), isFalse); + }); + + test("Test power_of_two 23 returns false", () { + expect(power_of_two(23), isFalse); + }); + + test("Test power_of_two 32 returns true", () { + expect(power_of_two(32), isTrue); + }); + + test("Test power_of_two 2234 returns false", () { + expect(power_of_two(2234), isFalse); + }); + + test("Test power_of_two 2048 returns true", () { + expect(power_of_two(2048), isTrue); + }); +} diff --git a/maths/relu_function.dart b/maths/relu_function.dart new file mode 100644 index 00000000..5f7d9872 --- /dev/null +++ b/maths/relu_function.dart @@ -0,0 +1,19 @@ +// Program to Implement RELU function +// RELU function is commonly used in Machine learning as an activation function + +int relu_func(var x) { + // here x passed is value passed in the function relu + if (x > 0) + return x; + else + return 0; +} + +//Driver function for RELU function +int main() { + var a = 5; + print(relu_func(a)); + var b = -1; + print(relu_func(b)); + return 0; +} diff --git a/maths/shreedharacharya.dart b/maths/shreedharacharya.dart new file mode 100644 index 00000000..99e66a83 --- /dev/null +++ b/maths/shreedharacharya.dart @@ -0,0 +1,24 @@ +import 'dart:math'; + +//this function return a list of roots of a quadratic equation +// [x1, x2] where x1 and x2 are roots of +// aX^2 + bX + c = 0 +List shreedharacharya(double a, double b, double c) { + double d = b * b - 4 * a * c; + List A = []; + if (d < 0) { + print('Imaginary roots'); + } else if (d == 0) { + A.add(-b / (2 * a)); + } else { + A.add((-b + sqrt(d)) / (2 * a)); + A.add((-b - sqrt(d)) / (2 * a)); + } + return A; +} + +void main() { + double a = 1.00, b = -4.00, c = 4.00; + List p = shreedharacharya(a, b, c); + print(p); +} diff --git a/maths/sieve_of_eratosthenes.dart b/maths/sieve_of_eratosthenes.dart new file mode 100644 index 00000000..ebe2dc64 --- /dev/null +++ b/maths/sieve_of_eratosthenes.dart @@ -0,0 +1,37 @@ +/* + * Source: + * https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes + * + * Description: + * Calculates prime numbers till a number n + * + * Time Complexity: + * O(n log(log(n))) + */ + +List sieve_of_eratosthenes(int n) { + // Input: n: int + // Output: is_prime: List denoting whether ith element is prime or not + List is_prime = new List.filled(n + 1, true); + is_prime[0] = false; + is_prime[1] = false; + for (int i = 2; i * i <= n; i++) { + if (is_prime[i]) { + for (int j = i * i; j <= n; j += i) { + // mark all multiples of i as false + is_prime[j] = false; + } + } + } + return is_prime; +} + +main() { + // Prints all the primes under 50 + List primes = sieve_of_eratosthenes(50); + for (int i = 2; i <= 50; i++) { + if (primes[i]) { + print(i); + } + } +} diff --git a/maths/sigmoid.dart b/maths/sigmoid.dart new file mode 100644 index 00000000..c2235164 --- /dev/null +++ b/maths/sigmoid.dart @@ -0,0 +1,16 @@ +import 'dart:math'; + +double sigmoid( + double x, + double a, +) //x is the function variable and a is the gain +{ + double p = exp(-a * x); + return 1 / (1 + p); +} + +void main() { + double gain = 1.00, x = 0.5; + double p = sigmoid(x, gain); + print(p); +} diff --git a/maths/sphenic_number.dart b/maths/sphenic_number.dart new file mode 100644 index 00000000..4f7725ea --- /dev/null +++ b/maths/sphenic_number.dart @@ -0,0 +1,40 @@ +import 'package:test/test.dart'; + +var arr = new List.filled(1001, true, growable: false); +void simple_seive() { + for (int p = 2; p * p < 1001; p++) { + if (arr[p]) { + for (int i = p * 2; i < 1001; i = i + p) arr[i] = false; + } + } +} + +bool sphenic_number(int N) { + var arr1 = new List.filled(9, 0, growable: false); + + var count = 0; + var j = 0; + + for (int i = 1; i <= N; i++) { + if (N % i == 0 && count < 9) { + count++; + arr1[j] = i; + j++; + } + } + + return (count == 8 && arr[arr1[0]] && arr[arr1[1]] && arr[arr1[2]]); +} + +void main() { + simple_seive(); + test("Test Sphenic_no returns false for non-sphenic numbers", () { + expect(sphenic_number(0), isFalse); + expect(sphenic_number(371), isFalse); + expect(sphenic_number(509), isFalse); + expect(sphenic_number(501), isFalse); + }); + test("Test sphenic_no returns true for sphenic numbers", () { + expect(sphenic_number(370), isTrue); + }); +} diff --git a/maths/symmetric_derivative.dart b/maths/symmetric_derivative.dart index 9cb1829c..d14c0e8d 100644 --- a/maths/symmetric_derivative.dart +++ b/maths/symmetric_derivative.dart @@ -7,6 +7,8 @@ double derivative(double Function(double) f, double x, [double h = 1e-10]) { void main() { print("derivative(sin, pi) = ${derivative(sin, pi)}, cos(pi) = ${cos(pi)}"); - print("derivative(sin, 2 * pi) = ${derivative(sin, 2 * pi)}, cos(2 * pi) = ${cos(2 * pi)}"); + print( + "derivative(sin, 2 * pi) = ${derivative(sin, 2 * pi)}, cos(2 * pi) = ${cos(2 * pi)}", + ); print("derivative(exp, 3) = ${derivative(exp, 3)}, exp(3) = ${exp(3)}"); } diff --git a/other/FizzBuzz.dart b/other/FizzBuzz.dart new file mode 100644 index 00000000..75883690 --- /dev/null +++ b/other/FizzBuzz.dart @@ -0,0 +1,23 @@ +//Title:FizzBuzz +// Author:ShivamVerma +// Email:shivamthegreat.sv@gmail.com + +// Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz". + +void main() { + fizzBuzz(); +} + +void fizzBuzz() { + for (int i = 1; i <= 100; i++) { + if (i % 3 == 0 && i % 5 == 0) { + print("FizzBuzz"); + } else if (i % 3 == 0) { + print("Fizz"); + } else if (i % 5 == 0) { + print("Buzz"); + } else { + print(i); + } + } +} diff --git a/other/LCM.dart b/other/LCM.dart index 3967cf31..3eefc880 100644 --- a/other/LCM.dart +++ b/other/LCM.dart @@ -11,29 +11,43 @@ */ //Recursive function to return gcd of a and b -double gcd(var a,var b){ - if(a == 0){ +int gcd(int a, int b) { + if (a == 0) { return b; } - return gcd(b % a,a); + return gcd(b % a, a); } //Function to return LCM of two numbers -double lcm(var a,var b){ - return (a * b) / gcd(a,b); +double lcm(int a, int b) { + return (a * b) / gcd(a, b); } //Driver program -void main(){ - var a,b; +void main() { + var a, b; //Test case1: a = 15; b = 20; //print the result - print("LCM of " + a.toString() + " and " + b.toString() + " is " + lcm(a,b).toString()); + print( + "LCM of " + + a.toString() + + " and " + + b.toString() + + " is " + + lcm(a, b).toString(), + ); //Test case2: a = 12; b = 18; //print the result - print("LCM of " + a.toString() + " and " + b.toString() + " is " + lcm(a,b).toString()); + print( + "LCM of " + + a.toString() + + " and " + + b.toString() + + " is " + + lcm(a, b).toString(), + ); } diff --git a/other/Moore_voting_algorithm.dart b/other/Moore_voting_algorithm.dart new file mode 100644 index 00000000..30806c58 --- /dev/null +++ b/other/Moore_voting_algorithm.dart @@ -0,0 +1,45 @@ +import 'package:test/test.dart'; + +int majorityElement(List arr, int n) { + arr.sort(); + + var count = 1, max_ele = -1, temp = arr[0], ele = 0, f = 0; + + for (int i = 1; i < n; i++) { + if (temp == arr[i]) { + count++; + } else { + count = 1; + temp = arr[i]; + } + if (max_ele < count) { + max_ele = count; + ele = arr[i]; + + if (max_ele > (n / 2)) { + f = 1; + break; + } + } + } + return (f == 1 ? ele : -1); +} + +// Driver code +void main() { + test("majorityElement", () { + List a1 = [1, 2, 2, 2, 2, 5, 1]; + expect(majorityElement(a1, a1.length), equals(2)); + + List a2 = [30, 30, 40, 30, 40, 30, 40]; + expect(majorityElement(a2, a2.length), equals(30)); + }); + + test("majorityElement returns -1 when there is no dominant element", () { + List a1 = [3, 3, 22, 21, 21, 5, 21]; + expect(majorityElement(a1, a1.length), equals(-1)); + + List a2 = [100, 4000, 220, 220, 220, 100, 4000]; + expect(majorityElement(a2, a2.length), equals(-1)); + }); +} diff --git a/other/N_bonacci.dart b/other/N_bonacci.dart new file mode 100644 index 00000000..14ba7b48 --- /dev/null +++ b/other/N_bonacci.dart @@ -0,0 +1,38 @@ +import 'package:test/test.dart'; + +List N_bonacci(int n, int m) { + List v = List.generate(m, (index) => 0); + var i; + for (i = 0; i < m; i++) { + v[i] = 0; + } + v[n - 1] = 1; + v[n] = 1; + for (i = n + 1; i < m; i++) { + v[i] = 2 * v[i - 1] - v[i - 1 - n]; + } + + return v; +} + +void main() { + test("For n=2 N_bonacci is same as fibbonaci", () { + expect(N_bonacci(2, 6), equals([0, 1, 1, 2, 3, 5])); + }); + + test("For n=3 N_bonacci is same as tribbonaci", () { + expect(N_bonacci(3, 7), equals([0, 0, 1, 1, 2, 4, 7])); + }); + + test("n=4 N_bonacci", () { + expect(N_bonacci(4, 10), equals([0, 0, 0, 1, 1, 2, 4, 8, 15, 29])); + }); + + test("n=6 N_bonacci", () { + expect(N_bonacci(6, 10), equals([0, 0, 0, 0, 0, 1, 1, 2, 4, 8])); + }); + + test("n=8 N_bonacci", () { + expect(N_bonacci(8, 10), equals([0, 0, 0, 0, 0, 0, 0, 1, 1, 2])); + }); +} diff --git a/other/binpow.dart b/other/binpow.dart new file mode 100644 index 00000000..c3650369 --- /dev/null +++ b/other/binpow.dart @@ -0,0 +1,20 @@ +// Effective computation of large exponents modulo a number +// Function binpow to calculate (x^n mod m) +int binPow(int a, int b, int m) { + int result = 1; + a %= m; + if (a == 0) return 0; + while (b > 0) { + if (b % 2 == 1) { + result = (result * a) % m; + } + b >>= 1; + a = (a * a) % m; + } + return result; +} + +void main() { + print('binary power of (2,5,13) = ' + binPow(2, 5, 13).toString()); + print('binary power of (5, 3,13) = ' + binPow(5, 3, 13).toString()); +} diff --git a/other/chinese_remainder_theorem.dart b/other/chinese_remainder_theorem.dart new file mode 100644 index 00000000..39af8935 --- /dev/null +++ b/other/chinese_remainder_theorem.dart @@ -0,0 +1,66 @@ +// Function to calculate modulo inverse. +int modular_inverse(int a, int m) { + // Temporary variable to store m to use later. + int temp = m; + + if (m == 1) { + return 0; + } + + int y = 0, x = 1, temp2, quotient, remainder; + + // Calculating x and y based on Euclid's algorithm + while (a > 1) { + quotient = (a / m).floor(); + remainder = a % m; + a = m; + m = remainder; + temp2 = y; + y = x - quotient * y; + x = temp2; + } + + // Making x positive if found negative + if (x < 0) { + x += temp; + } + + return x; +} + +// Driver function of the program +void main() { + // Taking input of the number array (num[i]). + print("Enter array of pairwise co-prime numbers:"); + + List numbers = [9, 8, 5, 7, 1]; + + // Taking input of remainder array (rem[i]). + print("Enter remainders:"); + + List remainders = [1, 2, 3, 4, 5]; + + num product = 1; + + // Length of the 'numbers' list. + int length = numbers.length; + + // Finding product of all the numbers. + for (int i = 0; i < length; i++) { + product *= numbers[i]; + } + + int temp; + num result = 0; + + // Summing the required values for all i according to the formula. + for (int i = 0; i < length; i++) { + temp = (product / numbers[i]).floor(); + result += temp * (remainders[i]) * modular_inverse(temp, numbers[i]); + } + + result = result % product; + + // Printing result + print("The value of 'x' by Chinese Remainder Theorem is $result."); +} diff --git a/other/collatz.dart b/other/collatz.dart index 0f59bb90..a509d8a8 100644 --- a/other/collatz.dart +++ b/other/collatz.dart @@ -8,22 +8,22 @@ //Email:stepfencurryxiao@gmail.com //Reference the C repo -void main(){ +void main() { //The number - double n = 20; + double n = 20; //curr_no stores number n double curr_no = n; //Loop till series reaches 1 - while(curr_no != 1){ + while (curr_no != 1) { //condition for even number - if(curr_no % 2 == 0){ + if (curr_no % 2 == 0) { curr_no = curr_no / 2; - print(curr_no.toString()+"->"); + print(curr_no.toString() + "->"); } //condition for odd number - else{ + else { curr_no = (curr_no * 3) + 1; - print(curr_no.toString()+"->"); + print(curr_no.toString() + "->"); } } print("1"); diff --git a/other/fisher_yates_shuffle.dart b/other/fisher_yates_shuffle.dart index 61952759..e6ba37a4 100644 --- a/other/fisher_yates_shuffle.dart +++ b/other/fisher_yates_shuffle.dart @@ -16,7 +16,7 @@ void shuffle(List collection) { } } -main(List args) { +main() { List someList = [1, 2, 3, 4, 5]; print(someList); shuffle(someList); diff --git a/other/haversine_formula.dart b/other/haversine_formula.dart index 653c9b80..caee0b3b 100644 --- a/other/haversine_formula.dart +++ b/other/haversine_formula.dart @@ -12,7 +12,7 @@ class Coordinates { Coordinates(this.latitude, this.longitude); } -double haversine(fi) => pow(sin(fi / 2), 2); +double haversine(fi) => pow(sin(fi / 2), 2).toDouble(); /// Convert [angle] to radians double radians(double angle) => (angle * pi) / 180; @@ -26,7 +26,8 @@ double distance(Coordinates p1, Coordinates p2) { double latitude2 = radians(p2.latitude); double longitudeChange = radians(p2.longitude - p1.longitude); - double a = haversine(latitudeChange) + + double a = + haversine(latitudeChange) + cos(latitude1) * cos(latitude2) * haversine(longitudeChange); double c = 2 * atan2(sqrt(a), sqrt(1 - a)); diff --git a/other/heaps_algorithm.dart b/other/heaps_algorithm.dart index 5b361fac..81c021e1 100644 --- a/other/heaps_algorithm.dart +++ b/other/heaps_algorithm.dart @@ -31,7 +31,7 @@ List> permutations(List collection) { return output; } -main(List args) { +main() { print(permutations([])); print(permutations([1, 2])); print(permutations([1, 2, 3])); diff --git a/other/kadaneAlgo.dart b/other/kadaneAlgo.dart new file mode 100644 index 00000000..e23b5065 --- /dev/null +++ b/other/kadaneAlgo.dart @@ -0,0 +1,29 @@ +// Program to find the Maximum contiguous sum (Kadane's Algorithm) +// Function to Calculate Maximum of Two Number +int max(int a, int b) { + if (a > b) + return a; + else + return b; +} + +// Function to find the Maximum contiguous Sum in the array +int maxSubArraySum(List a, int size) { + int max_so_far = a[0]; + int curr_max = a[0]; + + for (int i = 1; i < size; i++) { + curr_max = max(a[i], curr_max + a[i]); + max_so_far = max(max_so_far, curr_max); + } + return max_so_far; +} + +// main function for validation of the above +int main() { + List a = [-2, -3, 4, -1, -2, 1, 5, -3]; + int n = a.length; + int max_sum = maxSubArraySum(a, n); + print("Maximum contiguous sum is " + max_sum.toString()); + return 0; +} diff --git a/other/magic_number.dart b/other/magic_number.dart new file mode 100644 index 00000000..b13e92e7 --- /dev/null +++ b/other/magic_number.dart @@ -0,0 +1,20 @@ +import 'package:test/test.dart'; + +bool Magic_no(var x) { + var result = x % 9; + return result == 1; +} + +void main() { + test("Test Magic_no returns false for non-magic numbers", () { + expect(Magic_no(0), isFalse); + expect(Magic_no(371), isFalse); + expect(Magic_no(509), isFalse); + expect(Magic_no(501), isFalse); + }); + + test("Test Magic_no returns true for magic numbers", () { + expect(Magic_no(10), isTrue); + expect(Magic_no(370), isTrue); + }); +} diff --git a/other/swap_all_odd_and_even_bits.dart b/other/swap_all_odd_and_even_bits.dart new file mode 100644 index 00000000..36fa579e --- /dev/null +++ b/other/swap_all_odd_and_even_bits.dart @@ -0,0 +1,20 @@ +import 'package:test/test.dart'; + +//we are given an integer,the tast is to get its binary representation,swap all odd and even bits and print the new number +int swapbits(int n) { + return (((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1)); +} + +void main() { + test("swapbits returns 1 for 2", () { + expect(swapbits(2), equals(1)); + }); + + test("swapbits returns 23 for 43", () { + expect(swapbits(43), equals(23)); + }); + + test("swapbits returns 43 for 23", () { + expect(swapbits(23), equals(43)); + }); +} diff --git a/project_euler/problem_1/sol1.dart b/project_euler/problem_1/sol1.dart new file mode 100644 index 00000000..f5c5ddb3 --- /dev/null +++ b/project_euler/problem_1/sol1.dart @@ -0,0 +1,31 @@ +///Author: Shawn +///Email: stepfencurryxiao@gmail.com + +/* + * [Problem 1](https://projecteuler.net/problem=1) solution + * Problem Statement: + * If we list all the natural numbers below 10 that are multiples of 3 + * or 5, + * we get 3,5,6 and 9. The sum of these multiples is 23. + * Find the sum of all the multiples of 3 or 5 below N. + */ + +int sol(int t) { + int sum = 0; + int terms = (t - 1) ~/ 3; + sum += ((terms) * (6 + (terms - 1) * 3)) ~/ 2; // sum of an A.P. + terms = (t - 1) ~/ 5; + sum += ((terms) * (10 + (terms - 1) * 5)) ~/ 2; + terms = (t - 1) ~/ 15; + sum -= ((terms) * (30 + (terms - 1) * 15)) ~/ 2; + + return sum; +} + +int main() { + int value = sol(4); + print("solution(4): $value"); + value = sol(3); + print("solution(3): $value"); + return 0; +} diff --git a/project_euler/problem_10/sol10.dart b/project_euler/problem_10/sol10.dart new file mode 100644 index 00000000..ca0d1adf --- /dev/null +++ b/project_euler/problem_10/sol10.dart @@ -0,0 +1,68 @@ +/** + * Project Euler Problem 10: https://projecteuler.net/problem=10 + * Summation of primes + * The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. + * Find the sum of all the primes below two million. + */ + +import 'dart:math'; +import 'package:test/test.dart'; + +void main() { + print("Solution 1 => ${solution1(2000000)}"); + print("Solution 2 => ${solution2(2000000)}"); + + test("Test isPrime", () { + expect(isPrime(-2), false); + expect(isPrime(0), false); + expect(isPrime(1), false); + expect(isPrime(2), true); + }); + + test("Test solution1", () { + expect(solution1(10), 17); + expect(solution1(20), 77); + }); + + test("Test solution2", () { + expect(solution2(10), 17); + expect(solution2(20), 77); + }); +} + +int solution1(int n) { + var sum = 0; + + for (int i = 2; i < n; i++) { + if (isPrime(i)) sum += i; + } + return sum; +} + +int solution2(int n) { + if (n <= 2) return 0; + if (n <= 3) return 2; + + var sum = 5; + var i = 5; + + while (i < n) { + if (isPrime(i)) sum += i; + i += 2; + if (i < n && isPrime(i)) sum += i; + i += 4; + } + return sum; +} + +bool isPrime(int number) { + if (number <= 1) return false; + + var root = sqrt(number).floor(); + + for (int div = 2; div <= root; div++) { + if (number % div == 0) return false; + } + + return true; +} diff --git a/project_euler/problem_12/sol12.dart b/project_euler/problem_12/sol12.dart new file mode 100644 index 00000000..380aa59a --- /dev/null +++ b/project_euler/problem_12/sol12.dart @@ -0,0 +1,54 @@ +import 'dart:math'; + +List prime_sieve(int limit) { + int sieve_bound = (limit - 1) ~/ 2; + int upper_sqrt = (sqrt(limit).toInt() - 1) ~/ 2; + List prime_bits = List.generate(sieve_bound + 1, (_) => true); + + for (int i = 1; i <= upper_sqrt; ++i) + if (prime_bits[i]) + for (int j = i * (i + 1) * 2; j <= sieve_bound; j += 2 * i + 1) + prime_bits[j] = false; + + List primes = [2]; + for (int i = 1; i <= sieve_bound; ++i) + if (prime_bits[i]) primes.add(2 * i + 1); + + return primes; +} + +int prime_factorisation_number_of_divisors(int n, List primes) { + int nod = 1; + int remain = n; + for (int i = 0; i < primes.length; ++i) { + if (primes[i] * primes[i] > n) return nod * 2; + int power = 1; + while (remain % primes[i] == 0) { + power += 1; + remain ~/= primes[i]; + } + nod *= power; + if (remain == 1) break; + } + return nod; +} + +void main() { + int i = 2; + int count = 0; + int odd = 2; + int even = 2; + List primes = prime_sieve(500); + while (count < 500) { + even = i % 2 == 0 + ? prime_factorisation_number_of_divisors(i + 1, primes) + : even; + odd = i % 2 != 0 + ? prime_factorisation_number_of_divisors((i + 1) ~/ 2, primes) + : odd; + count = even * odd; + ++i; + } + int ans = (i * (i - 1) * 0.5).toInt(); + print("First Triangle Number with more than 500 divisors: $ans"); +} diff --git a/project_euler/problem_13/sol13.dart b/project_euler/problem_13/sol13.dart new file mode 100644 index 00000000..bf3c7267 --- /dev/null +++ b/project_euler/problem_13/sol13.dart @@ -0,0 +1,140 @@ +// Email : mau1361317@gmail.com + +/** + * [Problem 13](https://projecteuler.net/problem=13) solution + * Work out the first ten digits of the sum of the following one-hundred 50-digit numbers. + 37107287533902102798797998220837590246510135740250 + 46376937677490009712648124896970078050417018260538 + 74324986199524741059474233309513058123726617309629 + 91942213363574161572522430563301811072406154908250 + 23067588207539346171171980310421047513778063246676 + 89261670696623633820136378418383684178734361726757 + 28112879812849979408065481931592621691275889832738 + 44274228917432520321923589422876796487670272189318 + 47451445736001306439091167216856844588711603153276 + 70386486105843025439939619828917593665686757934951 + 62176457141856560629502157223196586755079324193331 + 64906352462741904929101432445813822663347944758178 + 92575867718337217661963751590579239728245598838407 + 58203565325359399008402633568948830189458628227828 + 80181199384826282014278194139940567587151170094390 + 35398664372827112653829987240784473053190104293586 + 86515506006295864861532075273371959191420517255829 + 71693888707715466499115593487603532921714970056938 + 54370070576826684624621495650076471787294438377604 + 53282654108756828443191190634694037855217779295145 + 36123272525000296071075082563815656710885258350721 + 45876576172410976447339110607218265236877223636045 + 17423706905851860660448207621209813287860733969412 + 81142660418086830619328460811191061556940512689692 + 51934325451728388641918047049293215058642563049483 + 62467221648435076201727918039944693004732956340691 + 15732444386908125794514089057706229429197107928209 + 55037687525678773091862540744969844508330393682126 + 18336384825330154686196124348767681297534375946515 + 80386287592878490201521685554828717201219257766954 + 78182833757993103614740356856449095527097864797581 + 16726320100436897842553539920931837441497806860984 + 48403098129077791799088218795327364475675590848030 + 87086987551392711854517078544161852424320693150332 + 59959406895756536782107074926966537676326235447210 + 69793950679652694742597709739166693763042633987085 + 41052684708299085211399427365734116182760315001271 + 65378607361501080857009149939512557028198746004375 + 35829035317434717326932123578154982629742552737307 + 94953759765105305946966067683156574377167401875275 + 88902802571733229619176668713819931811048770190271 + 25267680276078003013678680992525463401061632866526 + 36270218540497705585629946580636237993140746255962 + 24074486908231174977792365466257246923322810917141 + 91430288197103288597806669760892938638285025333403 + 34413065578016127815921815005561868836468420090470 + 23053081172816430487623791969842487255036638784583 + 11487696932154902810424020138335124462181441773470 + 63783299490636259666498587618221225225512486764533 + 67720186971698544312419572409913959008952310058822 + 95548255300263520781532296796249481641953868218774 + 76085327132285723110424803456124867697064507995236 + 37774242535411291684276865538926205024910326572967 + 23701913275725675285653248258265463092207058596522 + 29798860272258331913126375147341994889534765745501 + 18495701454879288984856827726077713721403798879715 + 38298203783031473527721580348144513491373226651381 + 34829543829199918180278916522431027392251122869539 + 40957953066405232632538044100059654939159879593635 + 29746152185502371307642255121183693803580388584903 + 41698116222072977186158236678424689157993532961922 + 62467957194401269043877107275048102390895523597457 + 23189706772547915061505504953922979530901129967519 + 86188088225875314529584099251203829009407770775672 + 11306739708304724483816533873502340845647058077308 + 82959174767140363198008187129011875491310547126581 + 97623331044818386269515456334926366572897563400500 + 42846280183517070527831839425882145521227251250327 + 55121603546981200581762165212827652751691296897789 + 32238195734329339946437501907836945765883352399886 + 75506164965184775180738168837861091527357929701337 + 62177842752192623401942399639168044983993173312731 + 32924185707147349566916674687634660915035914677504 + 99518671430235219628894890102423325116913619626622 + 73267460800591547471830798392868535206946944540724 + 76841822524674417161514036427982273348055556214818 + 97142617910342598647204516893989422179826088076852 + 87783646182799346313767754307809363333018982642090 + 10848802521674670883215120185883543223812876952786 + 71329612474782464538636993009049310363619763878039 + 62184073572399794223406235393808339651327408011116 + 66627891981488087797941876876144230030984490851411 + 60661826293682836764744779239180335110989069790714 + 85786944089552990653640447425576083659976645795096 + 66024396409905389607120198219976047599490197230297 + 64913982680032973156037120041377903785566085089252 + 16730939319872750275468906903707539413042652315011 + 94809377245048795150954100921645863754710598436791 + 78639167021187492431995700641917969777599028300699 + 15368713711936614952811305876380278410754449733078 + 40789923115535562561142322423255033685442488917353 + 44889911501440648020369068063960672322193204149535 + 41503128880339536053299340368006977710650566631954 + 81234880673210146739058568557934581403627822703280 + 82616570773948327592232845941706525094512325230608 + 22918802058777319719839450180888072429661980811197 + 77158542502016545090413245809786882778948721859617 + 72107838435069186155435662884062257473692284509516 + 20849603980134001723930671666823555245252804609722 + 53503534226472524250874054075591789781264330331690 + */ + +void main() { + List numbers = + "37107287533902102798797998220837590246510135740250 46376937677490009712648124896970078050417018260538 74324986199524741059474233309513058123726617309629 91942213363574161572522430563301811072406154908250 23067588207539346171171980310421047513778063246676 89261670696623633820136378418383684178734361726757 28112879812849979408065481931592621691275889832738 44274228917432520321923589422876796487670272189318 47451445736001306439091167216856844588711603153276 70386486105843025439939619828917593665686757934951 62176457141856560629502157223196586755079324193331 64906352462741904929101432445813822663347944758178 92575867718337217661963751590579239728245598838407 58203565325359399008402633568948830189458628227828 80181199384826282014278194139940567587151170094390 35398664372827112653829987240784473053190104293586 86515506006295864861532075273371959191420517255829 71693888707715466499115593487603532921714970056938 54370070576826684624621495650076471787294438377604 53282654108756828443191190634694037855217779295145 36123272525000296071075082563815656710885258350721 45876576172410976447339110607218265236877223636045 17423706905851860660448207621209813287860733969412 81142660418086830619328460811191061556940512689692 51934325451728388641918047049293215058642563049483 62467221648435076201727918039944693004732956340691 15732444386908125794514089057706229429197107928209 55037687525678773091862540744969844508330393682126 18336384825330154686196124348767681297534375946515 80386287592878490201521685554828717201219257766954 78182833757993103614740356856449095527097864797581 16726320100436897842553539920931837441497806860984 48403098129077791799088218795327364475675590848030 87086987551392711854517078544161852424320693150332 59959406895756536782107074926966537676326235447210 69793950679652694742597709739166693763042633987085 41052684708299085211399427365734116182760315001271 65378607361501080857009149939512557028198746004375 35829035317434717326932123578154982629742552737307 94953759765105305946966067683156574377167401875275 88902802571733229619176668713819931811048770190271 25267680276078003013678680992525463401061632866526 36270218540497705585629946580636237993140746255962 24074486908231174977792365466257246923322810917141 91430288197103288597806669760892938638285025333403 34413065578016127815921815005561868836468420090470 23053081172816430487623791969842487255036638784583 11487696932154902810424020138335124462181441773470 63783299490636259666498587618221225225512486764533 67720186971698544312419572409913959008952310058822 95548255300263520781532296796249481641953868218774 76085327132285723110424803456124867697064507995236 37774242535411291684276865538926205024910326572967 23701913275725675285653248258265463092207058596522 29798860272258331913126375147341994889534765745501 18495701454879288984856827726077713721403798879715 38298203783031473527721580348144513491373226651381 34829543829199918180278916522431027392251122869539 40957953066405232632538044100059654939159879593635 29746152185502371307642255121183693803580388584903 41698116222072977186158236678424689157993532961922 62467957194401269043877107275048102390895523597457 23189706772547915061505504953922979530901129967519 86188088225875314529584099251203829009407770775672 11306739708304724483816533873502340845647058077308 82959174767140363198008187129011875491310547126581 97623331044818386269515456334926366572897563400500 42846280183517070527831839425882145521227251250327 55121603546981200581762165212827652751691296897789 32238195734329339946437501907836945765883352399886 75506164965184775180738168837861091527357929701337 62177842752192623401942399639168044983993173312731 32924185707147349566916674687634660915035914677504 99518671430235219628894890102423325116913619626622 73267460800591547471830798392868535206946944540724 76841822524674417161514036427982273348055556214818 97142617910342598647204516893989422179826088076852 87783646182799346313767754307809363333018982642090 10848802521674670883215120185883543223812876952786 71329612474782464538636993009049310363619763878039 62184073572399794223406235393808339651327408011116 66627891981488087797941876876144230030984490851411 60661826293682836764744779239180335110989069790714 85786944089552990653640447425576083659976645795096 66024396409905389607120198219976047599490197230297 64913982680032973156037120041377903785566085089252 16730939319872750275468906903707539413042652315011 94809377245048795150954100921645863754710598436791 78639167021187492431995700641917969777599028300699 15368713711936614952811305876380278410754449733078 40789923115535562561142322423255033685442488917353 44889911501440648020369068063960672322193204149535 41503128880339536053299340368006977710650566631954 81234880673210146739058568557934581403627822703280 82616570773948327592232845941706525094512325230608 22918802058777319719839450180888072429661980811197 77158542502016545090413245809786882778948721859617 72107838435069186155435662884062257473692284509516 20849603980134001723930671666823555245252804609722 53503534226472524250874054075591789781264330331690" + .split(' ') + .map((e) => BigInt.parse(e)) + .toList(); + String solution_1 = "${solution1(numbers)}"; + print("Solution 1 => " + solution_1.substring(0, 10)); + + String solution_2 = "${solution2(numbers)}"; + print("Solution 2 => " + solution_2.substring(0, 10)); + + String solution_3 = "${solution3(numbers)}"; + print("Solution 3 => " + solution_3.substring(0, 10)); +} + +BigInt solution1(List numbers) { + return numbers.reduce((n1, n2) => n1 + n2); +} + +BigInt solution2(List numbers) { + BigInt result = new BigInt.from(0); + numbers.forEach((element) => result += element); + return result; +} + +BigInt solution3(List numbers) { + BigInt result = new BigInt.from(0); + for (var i = 0; i < numbers.length; i++) { + result += numbers[i]; + } + return result; +} diff --git a/project_euler/problem_17/sol17.dart b/project_euler/problem_17/sol17.dart new file mode 100644 index 00000000..6a5eb24d --- /dev/null +++ b/project_euler/problem_17/sol17.dart @@ -0,0 +1,118 @@ +/// Author: Pasan Godamune +/// Email: pasanjg@gmail.com + +/** + * [Problem 17](https://projecteuler.net/problem=17) solution + * Problem Statement: + * If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total. + * If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used? + * + * NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. + * The use of "and" when writing out numbers is in compliance with British usage. + */ + +import 'dart:math'; + +const ONES = [ + 'One', + 'Two', + 'Three', + 'Four', + 'Five', + 'Six', + 'Seven', + 'Eight', + 'Nine', + 'Ten', +]; + +const TEN_TWENTY = [ + 'Eleven', + 'Twelve', + 'Thirteen', + 'Fourteen', + 'Fifteen', + 'Sixteen', + 'Seventeen', + 'Eighteen', + 'Nineteen', +]; + +const TENS = [ + 'Ten', + 'Twenty', + 'Thirty', + 'Forty', // [It's 'Forty' NOT 'Fourty'](https://www.grammarly.com/blog/forty-fourty/) + 'Fifty', + 'Sixty', + 'Seventy', + 'Eighty', + 'Ninety', +]; + +const HUNDRED = 'Hundred'; +const THOUSDAND = 'Thousand'; +const AND = 'And'; + +String inWords = ""; + +String convertToWords(int number) { + String numString = number.toString(); + int length = numString.length; + int place = pow(10, length - 1).toInt(); + + if (number == 0) return inWords = "Zero"; + + if (length == 1) { + inWords = ONES[number - 1]; + } + + if (length == 2) { + inWords = TENS[(number / place).floor() - 1]; + + if (number % place != 0) { + if (number < 20) { + return inWords = TEN_TWENTY[(number % place) - 1]; + } + + inWords += convertToWords(number % place); + } + } + + if (length == 3) { + inWords = convertToWords((number / place).floor()) + HUNDRED; + + if (number % place != 0) { + inWords += AND + convertToWords(number % place); + } + } + + if (length == 4) { + inWords = convertToWords((number / place).floor()) + THOUSDAND; + + if (number % place != 0) { + inWords += AND + convertToWords(number % place); + } + } + + return inWords; +} + +calculateWithRange({int start = 1, end = 1000}) { + int count = 0; + + if (end > 1000) { + print("Max safe range is 0 - 1000 inclusive"); + return; + } + + for (int i = start; i <= end; i++) { + count += convertToWords(i).length; + } + + print(count); +} + +void main() { + calculateWithRange(start: 1, end: 1000); // 21124 +} diff --git a/project_euler/problem_2/sol2.dart b/project_euler/problem_2/sol2.dart new file mode 100644 index 00000000..1ef37973 --- /dev/null +++ b/project_euler/problem_2/sol2.dart @@ -0,0 +1,42 @@ +//Title:Project Euler Prob 2 - Even Fibonacci numbers +// Author:ShivamVerma +// Email:shivamthegreat.sv@gmail.com + +// Each new term in the Fibonacci sequence is generated by adding the previous two terms. +// By starting with 1 and 2, the first 10 terms will be: + +// 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... + +// By considering the terms in the Fibonacci sequence whose values do not exceed four million, +// find the sum of the even-valued terms. + +int evenFibSum(int limit) { + if (limit < 2) return 0; + + // Initialize first two even prime numbers + // and their sum + int ef1 = 0, ef2 = 2; + int sum = ef1 + ef2; + + // calculating sum of even Fibonacci value + while (ef2 <= limit) { + // get next even value of Fibonacci sequence + int ef3 = 4 * ef2 + ef1; + + // If we go beyond limit, we break loop + if (ef3 > limit) break; + + // Move to next even number and update sum + ef1 = ef2; + ef2 = ef3; + sum += ef2; + } + + return sum; +} + +//driver code +void main() { + int limit = 4000000; + print(evenFibSum(limit)); +} diff --git a/project_euler/problem_20/sol20.dart b/project_euler/problem_20/sol20.dart new file mode 100644 index 00000000..7fa45988 --- /dev/null +++ b/project_euler/problem_20/sol20.dart @@ -0,0 +1,45 @@ +/* +Problem 20: Factorial digit sum + +n! means n × (n − 1) × ... × 3 × 2 × 1 +For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, +and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27. +Find the sum of the digits in the number 100! +*/ + +import 'package:test/test.dart'; + +// To Calculate Factorial +int factorial(int number) { + int factorial = 1; + for (int i = number; i >= 1; i--) { + factorial *= i; + } + return factorial; +} + +// To Calculate Sum +int sum(int number) { + int sum = 0; + for (int i = factorial(number); i > 0; i = (i / 10).floor()) { + sum += (i % 10); + } + return sum; +} + +// Driver Code +void main() { + group("Solution 20", () { + test("Test 1", () { + expect(1, sum(1)); + }); + + test("Test 2", () { + expect(3, sum(5)); + }); + + test("Test 3", () { + expect(27, sum(10)); + }); + }); +} diff --git a/project_euler/problem_3/sol3.dart b/project_euler/problem_3/sol3.dart new file mode 100644 index 00000000..ca292c33 --- /dev/null +++ b/project_euler/problem_3/sol3.dart @@ -0,0 +1,15 @@ +//Title:Project Euler Prob 3 +// Author:Shivam Verma +// Email:shivamthegreat.sv@gmail.com + +// The prime factors of 13195 are 5, 7, 13 and 29. + +// What is the largest prime factor of the number 600851475143 ? + +void main() { + double i, n = 600851475143; + + for (i = 3; n > 1; i += 2) while (n % i == 0) n /= i; + + print(i - 2); +} diff --git a/project_euler/problem_4/sol4.dart b/project_euler/problem_4/sol4.dart new file mode 100644 index 00000000..d79e2a18 --- /dev/null +++ b/project_euler/problem_4/sol4.dart @@ -0,0 +1,32 @@ +// Author : Devmaufh +// Email : mau1361317@gmail.com + +/** + * [Problem 4](https://projecteuler.net/problem=4) solution + * Problem Statement: + * A palindromic number reads the same both ways. + * The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. + * Find the largest palindrome made from the product of two 3-digit numbers. + */ + +void main() { + int max = 0; + for (int i = 100; i < 1000; i++) { + for (int j = 100; j < 1000; j++) { + int result = i * j; + if (isPanlindrome("$result")) { + if (result > max) { + max = result; + } + } + } + } + print("MAX $max"); +} + +bool isPanlindrome(String word) { + for (int i = 0; i < word.length ~/ 2; i++) { + if (word[i] != word[word.length - i - 1]) return false; + } + return true; +} diff --git a/project_euler/problem_5/sol5.dart b/project_euler/problem_5/sol5.dart new file mode 100644 index 00000000..09600625 --- /dev/null +++ b/project_euler/problem_5/sol5.dart @@ -0,0 +1,27 @@ +// Author : Devmaufh +// Email : mau1361317@gmail.com + +/** + * [Problem 5](https://projecteuler.net/problem=5) solution + * Problem Statement: + * 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. + * What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? + */ + +void main() { + int number = 21; + LOOP: + while (true) { + bool isSolution = true; + for (int i = 1; i <= 21; i++) { + if (number % i != 0) { + isSolution = false; + break; // Break if have a remainder + } + } + if (isSolution) + break LOOP; //If any number hasn't a remainder, break main loop because we found the solution + number++; + } + print("Solution problem 5 = $number"); +} diff --git a/project_euler/problem_6/sol6.dart b/project_euler/problem_6/sol6.dart new file mode 100644 index 00000000..8c96edbb --- /dev/null +++ b/project_euler/problem_6/sol6.dart @@ -0,0 +1,34 @@ +/// Author: Pasan Godamune +/// Email: pasanjg@gmail.com + +/** + * [Problem 6](https://projecteuler.net/problem=6) solution + * Problem Statement: + * The sum of the squares of the first ten natural numbers is, + * 1^2 + 2^2 + … + 10^2 = 385 + * The square of the sum of the first ten natural numbers is, + * (1 + 2 + … + 10)^2 = 552 = 3025 + * Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640. + * Find the difference between the sum of the squares of the first one hundred natural numbers natural numbers and the square of the sum. + */ + +import 'dart:math'; + +squareDifference(n) { + return squareSumOfFirst(n) - sumOfSquare(n); +} + +sumOfSquare(n) { + return (((n * (n + 1)) * (n + (n + 1))) / 6); +} + +squareSumOfFirst(n) { + return pow((n + 1) * (n / 2), 2); +} + +void main() { + int n = 100; + print(squareDifference(n)); + + /// 25164150 +} diff --git a/project_euler/problem_7/sol7.dart b/project_euler/problem_7/sol7.dart new file mode 100644 index 00000000..f93399eb --- /dev/null +++ b/project_euler/problem_7/sol7.dart @@ -0,0 +1,27 @@ +// Author : Devmaufh +// Email : mau1361317@gmail.com + +/** + * [Problem 7](https://projecteuler.net/problem=7) solution + * Problem Statement: + * By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. + * What is the 10 001st prime number? + */ + +void main() { + int numberOfPrimes = 0; + int number = 1; + while (numberOfPrimes < 10001) { + number++; + if (isPrime(number)) { + numberOfPrimes++; + } + } + print(" 10 001st prime number is => $number "); +} + +bool isPrime(int number) { + if (number < 2) return false; + for (int i = 2; i < number; i++) if (number % i == 0) return false; + return true; +} diff --git a/project_euler/problem_8/sol8.dart b/project_euler/problem_8/sol8.dart new file mode 100644 index 00000000..4a1449e6 --- /dev/null +++ b/project_euler/problem_8/sol8.dart @@ -0,0 +1,72 @@ +/// Author: Pasan Godamune +/// Email: pasanjg@gmail.com + +/** + * [Problem 8](https://projecteuler.net/problem=8) solution + * Problem Statement: + * The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832. + + 73167176531330624919225119674426574742355349194934 + 96983520312774506326239578318016984801869478851843 + 85861560789112949495459501737958331952853208805511 + 12540698747158523863050715693290963295227443043557 + 66896648950445244523161731856403098711121722383113 + 62229893423380308135336276614282806444486645238749 + 30358907296290491560440772390713810515859307960866 + 70172427121883998797908792274921901699720888093776 + 65727333001053367881220235421809751254540594752243 + 52584907711670556013604839586446706324415722155397 + 53697817977846174064955149290862569321978468622482 + 83972241375657056057490261407972968652414535100474 + 82166370484403199890008895243450658541227588666881 + 16427171479924442928230863465674813919123162824586 + 17866458359124566529476545682848912883142607690042 + 24219022671055626321111109370544217506941658960408 + 07198403850962455444362981230987879927244284909188 + 84580156166097919133875499200524063689912560717606 + 05886116467109405077541002256983155200055935729725 + 71636269561882670428252483600823257530420752963450 + + * Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. + * What is the value of this product? + */ + +void main() { + String series = + "73167176531330624919225119674426574742355349194934" + "96983520312774506326239578318016984801869478851843" + "85861560789112949495459501737958331952853208805511" + "12540698747158523863050715693290963295227443043557" + "66896648950445244523161731856403098711121722383113" + "62229893423380308135336276614282806444486645238749" + "30358907296290491560440772390713810515859307960866" + "70172427121883998797908792274921901699720888093776" + "65727333001053367881220235421809751254540594752243" + "52584907711670556013604839586446706324415722155397" + "53697817977846174064955149290862569321978468622482" + "83972241375657056057490261407972968652414535100474" + "82166370484403199890008895243450658541227588666881" + "16427171479924442928230863465674813919123162824586" + "17866458359124566529476545682848912883142607690042" + "24219022671055626321111109370544217506941658960408" + "07198403850962455444362981230987879927244284909188" + "84580156166097919133875499200524063689912560717606" + "05886116467109405077541002256983155200055935729725" + "71636269561882670428252483600823257530420752963450"; + + largestAdjacentNumbers(series, {adjacentLength = 4}) { + var largestProduct = 0; + + for (int i = 0; i < series.length - adjacentLength + 1; i++) { + var subset = series.substring(i, adjacentLength + i); + + var numList = subset.split('').map((x) => int.parse(x)); + var product = numList.reduce((a, b) => a * b); + + if (product > largestProduct) largestProduct = product; + } + return largestProduct; + } + + print(largestAdjacentNumbers(series, adjacentLength: 13)); // 23514624000 +} diff --git a/project_euler/problem_9/sol9.dart b/project_euler/problem_9/sol9.dart new file mode 100644 index 00000000..97a6a4b8 --- /dev/null +++ b/project_euler/problem_9/sol9.dart @@ -0,0 +1,24 @@ +// Author : Devmaufh +// Email : mau1361317@gmail.com + +/** + * [Problem 9](https://projecteuler.net/problem=8) solution + * A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, + * a^2 + b^2 = c^2 + * For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2. + * There exists exactly one Pythagorean triplet for which a + b + c = 1000. + * Find the product abc. + */ + +void main() { + for (int i = 0; i <= 300; ++i) { + for (int j = 0; j <= 400; ++j) { + int k = 1000 - i - j; + if (i * i + j * j == k * k) { + var sol = i * j * k; + print("Solution : $sol"); + break; + } + } + } +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 00000000..5f2cab02 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,13 @@ +name: the_algorithms_dart + +repository: https://github.com/TheAlgorithms/Dart + +dependencies: + test: ^1.15.4 + coverage: ^1.6.0 + +dev_dependencies: + stack: ^0.2.1 + +environment: + sdk: ^3.11.0 diff --git a/search/binary_Search.dart b/search/binary_Search.dart index a3dbec8d..b89b5933 100644 --- a/search/binary_Search.dart +++ b/search/binary_Search.dart @@ -18,15 +18,15 @@ int binary_search(List a, int l, int r, int x) { } void main() { - var list = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]; - var x = 55; + List list = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]; + int x = 55; int n = list.length; - var index = binary_search(list, 0, n - 1, x); + int index = binary_search(list, 0, n - 1, x); print('list:'); print(list); if (index != -1) { - print(x.toString() + ' found at positions: ' + index.toString()); + print('$x found at positions: $index'); } else { - print(x.toString() + ' Not found'); + print('$x Not found'); } } diff --git a/search/binary_search_recursion.dart b/search/binary_search_recursion.dart index 3ee40a68..359449f6 100644 --- a/search/binary_search_recursion.dart +++ b/search/binary_search_recursion.dart @@ -22,9 +22,17 @@ int binarySearch(List list, int low, int high, int key) { return mid; /* found */ } else if (key > list[mid]) { return binarySearch( - list, mid + 1, high, key); /* search in range[mid + 1, high] */ + list, + mid + 1, + high, + key, + ); /* search in range[mid + 1, high] */ } else { return binarySearch( - list, low, mid - 1, key); /* search in range[low, mid - 1] */ + list, + low, + mid - 1, + key, + ); /* search in range[low, mid - 1] */ } } diff --git a/search/fibonacci_Search.dart b/search/fibonacci_Search.dart index 972355a5..ea7069e5 100644 --- a/search/fibonacci_Search.dart +++ b/search/fibonacci_Search.dart @@ -2,7 +2,7 @@ //Author:Shawn //Email:stepfencurryxiao@gmail.com -int fibMaonaccianSearch(List arr,int x,int n){ +int fibMaonaccianSearch(List arr, int x, int n) { //Initialize fibonacci numbers //(m - 2)'th Fibonacci No int fibMMm2 = 0; @@ -10,89 +10,79 @@ int fibMaonaccianSearch(List arr,int x,int n){ int fibMMm1 = 1; //m'th Fibonacci int fibM = fibMMm2 + fibMMm1; - + //fibM is going to store the smallest Fibonacci //Number greater than or equal to n - while(fibM < n){ + while (fibM < n) { fibMMm2 = fibMMm1; fibMMm1 = fibM; fibM = fibMMm2 + fibMMm1; } - + // Marks the eliminated range from front int offset = -1; - + /*While three are elements to be inspected. * Note that we compare arr[fibMMm2] with x. * When fibM becomes 1, * fibMm2 becomes 0 */ - while(fibM > 1){ + while (fibM > 1) { //Check if fibMMm2 is a valid location - + //sets i to the min. of (offset + fibMMm2) and (n - 1) - int i = ((offset + fibMMm2) < (n -1)) ? - (offset + fibMMm2) : (n - 1); - + int i = ((offset + fibMMm2) < (n - 1)) ? (offset + fibMMm2) : (n - 1); + /* If x is greater than the value at index fibMmm2 * cut the subarray array from offset to i */ - - if(arr[i] < x){ + + if (arr[i] < x) { fibM = fibMMm1; fibMMm1 = fibMMm2; fibMMm2 = fibM - fibMMm1; offset = i; } - /* If x is greater than the value at index fibMmm2 * cut the subarray array after i + 1. */ - else if(arr[i] > x){ - fibM =fibMMm2; + else if (arr[i] > x) { + fibM = fibMMm2; fibMMm1 = fibMMm1 - fibMMm2; fibMMm2 = fibM - fibMMm1; } - //elwment found.Return index - else{ + else { return i; } - } - + //Comparing the last element with x - if(arr[offset + 1] == x){ + if (arr[offset + 1] == x) { return offset + 1; } - + //element not found :( return -1; } -void main(){ +void main() { //Get the array - var arr = [1,2,3,4,5,6,7,8,9,10]; - + var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + var result; - + //Print the array print(arr); - + //The size of the array var n = arr.length; - + //Key to be searched in the array var key = 7; - + //Search the key using ternarySearch - result = fibMaonaccianSearch(arr,key,n); - + result = fibMaonaccianSearch(arr, key, n); + //Print the result print("Index of " + key.toString() + " is " + result.toString()); - - } - - - - diff --git a/search/interpolation_Search.dart b/search/interpolation_Search.dart index 12d08dd8..5e45089c 100644 --- a/search/interpolation_Search.dart +++ b/search/interpolation_Search.dart @@ -12,36 +12,35 @@ //Author:Shawn //Email:stepfencurryxiao@gmail.com -int interpolationSearch(List arr, var n, var key) -{ - int low = 0, high = n - 1; - while (low <= high && key >= arr[low] && key <= arr[high]) { - /* Calculate the nearest posible position of key */ - int pos = low + ((key - arr[low]) * (high - low)) / (arr[high] - arr[low]); - if (key > arr[pos]) - low = pos + 1; - else if (key < arr[pos]) - high = pos - 1; - else /* Found */ - return pos; - } - /* Not found */ - return -1; +int interpolationSearch(List arr, int n, int key) { + int low = 0, high = n - 1; + while (low <= high && key >= arr[low] && key <= arr[high]) { + /* Calculate the nearest possible position of key */ + int pos = + low + + (((key - arr[low]) * (high - low)) / (arr[high] - arr[low])).round(); + if (key > arr[pos]) + low = pos + 1; + else if (key < arr[pos]) + high = pos - 1; + else /* Found */ + return pos; + } + /* Not found */ + return -1; } - -int main() -{ - //Get the arr - List arr = [0,1,2,3,4,5,6,7,8,9]; - //The size of the arr - var n = arr.length; - //The Key - var key = 5; - print("I want to found $key at $arr"); - //Get the index - var index = interpolationSearch(arr, n, key); - //print the result - print("Element found at position: $index"); - return 0; +int main() { + //Get the arr + List arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + //The size of the arr + var n = arr.length; + //The Key + var key = 5; + print("I want to found $key at $arr"); + //Get the index + var index = interpolationSearch(arr, n, key); + //print the result + print("Element found at position: $index"); + return 0; } diff --git a/search/linear_Search.dart b/search/linear_Search.dart index 80639b19..b568cdef 100644 --- a/search/linear_Search.dart +++ b/search/linear_Search.dart @@ -1,5 +1,5 @@ -int linear_search(List a, number) { - for (var i = 0; i < a.length; i++) { +int linear_search(List a, number) { + for (int i = 0; i < a.length; i++) { if (a[i] == number) { return i; } @@ -8,14 +8,14 @@ int linear_search(List a, number) { } void main() { - var list = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]; - var x = 15; - var index = linear_search(list, x); + List list = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]; + int x = 15; + int index = linear_search(list, x); print('list:'); print(list); if (index != -1) { - print(x.toString() + ' found at positions: ' + index.toString()); + print('$x found at positions: $index'); } else { - print(x.toString() + ' Not found'); + print('$x Not found'); } } diff --git a/search/peak_element.dart b/search/peak_element.dart new file mode 100644 index 00000000..6dc027a2 --- /dev/null +++ b/search/peak_element.dart @@ -0,0 +1,49 @@ +import 'package:test/test.dart'; + +int findPeakUtil(List arr, int low, int high, int n) { + var x = (low + high) / 2; + int mid = x.toInt(); + if ((mid == 0 || arr[mid - 1] <= arr[mid]) && + (mid == n - 1 || arr[mid + 1] <= arr[mid])) + return mid; + else if (mid > 0 && arr[mid - 1] > arr[mid]) + return findPeakUtil(arr, low, (mid - 1), n); + else + return findPeakUtil(arr, (mid + 1), high, n); +} + +int findPeak(List arr, int n) { + return findPeakUtil(arr, 0, n - 1, n); +} + +void main() { + test("findPeak returns 2 for [1, 3, 20, 6, 1, 2]", () { + List lst = [1, 3, 20, 6, 1, 2]; + expect(findPeak(lst, lst.length), equals(2)); + }); + + test("findPeak returns 3 for [1, 3, 20, 32, 1, 2]", () { + List lst = [1, 3, 20, 32, 1, 2]; + expect(findPeak(lst, lst.length), equals(3)); + }); + + test("findPeak returns 2 for [321, 4353, 22320, 232, 23, 223]", () { + List lst = [321, 4353, 22320, 232, 23, 223]; + expect(findPeak(lst, lst.length), equals(2)); + }); + + test("findPeak returns 2 for [121, 54, 2100, 36, 155, 90]", () { + List lst = [121, 54, 2100, 36, 155, 90]; + expect(findPeak(lst, lst.length), equals(2)); + }); + + test("findPeak returns 2 for [5, 10, 20, 15]", () { + List lst = [5, 10, 20, 15]; + expect(findPeak(lst, lst.length), equals(2)); + }); + + test("findPeak returns 1 for [10, 20, 15, 2, 23, 90, 67]", () { + List lst = [10, 20, 15, 2, 23, 90, 67]; + expect(findPeak(lst, lst.length), equals(1)); + }); +} diff --git a/search/ternary_Search.dart b/search/ternary_Search.dart index 9fa805d5..b9526ee8 100644 --- a/search/ternary_Search.dart +++ b/search/ternary_Search.dart @@ -2,68 +2,62 @@ //Author:Shawn //Email:stepfencurryxiao@gmail.com -int ternarySearch(var l,var r,var key,var arr){ - if(r >= 1){ - +int ternarySearch(var l, var r, var key, var arr) { + if (r >= 1) { //Find the mid1 and mid2 var mid1 = (l + (r - l) / 3).toInt(); var mid2 = (r - (r - 1) / 3).toInt(); - + //Check if key is present at any mid - if(arr[mid1] == key) - return mid1; - - if(arr[mid2] == key) - return mid2; - + if (arr[mid1] == key) return mid1; + + if (arr[mid2] == key) return mid2; + /*Since Key is not present at mid * check in which region it is present * then repeat the Search operation * in that region */ - - if(key < arr[mid1]){ + + if (key < arr[mid1]) { //The Key lies in between 1 and mid1 - return ternarySearch(l,mid1 - 1,key,arr); - } - else if(key > arr[mid2]){ + return ternarySearch(l, mid1 - 1, key, arr); + } else if (key > arr[mid2]) { //The key lies in between mid2 and r - return ternarySearch(mid2 + 1,r,key,arr); - } - else{ + return ternarySearch(mid2 + 1, r, key, arr); + } else { //The key lies in between mid1 and mid2 - return ternarySearch(mid1 + 1,mid2 - 1,key,arr); + return ternarySearch(mid1 + 1, mid2 - 1, key, arr); } } - + //Key not found return -1; } //Driver code -void main(){ - var l,r,p,key; - +void main() { + var l, r, p, key; + //Get the array - var arr = [1,2,3,4,5,6,7,8,9,10]; - + var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + //Print the array print(arr); - + //Starting index l = 0; - + // length of array r = arr.length; - + //Checking for 5 //Key to be searched in the array key = 5; - + //Search the key using ternarySearch - p = ternarySearch(l,r,key,arr); - + p = ternarySearch(l, r, key, arr); + //Print the result print("Index of " + key.toString() + " is " + p.toString()); - } diff --git a/sort/bubble_Sort.dart b/sort/bubble_Sort.dart index 3dd5010c..a2e56f04 100644 --- a/sort/bubble_Sort.dart +++ b/sort/bubble_Sort.dart @@ -3,8 +3,11 @@ import 'dart:math' show Random; //main function,the program start void main() { final seed = 100, rnd = Random(), length = 100; - var list = - List.generate(length, (i) => rnd.nextInt(seed), growable: false); + var list = List.generate( + length, + (i) => rnd.nextInt(seed), + growable: false, + ); print('before sorting:'); print(list); print('---------------------------------------------'); diff --git a/sort/cocktail_sort.dart b/sort/cocktail_sort.dart new file mode 100644 index 00000000..721a51db --- /dev/null +++ b/sort/cocktail_sort.dart @@ -0,0 +1,39 @@ +void cocktailSort(List lst) //function to sort a list +{ + bool swap_done = true; + do { + swap_done = false; + for (int i = 0; i < lst.length - 2; i++) { + swap_done = swapItemCocktail(lst, i, swap_done); + } + + if (swap_done) { + swap_done = false; + for (int i = lst.length - 2; i >= 0; i--) { + swap_done = swapItemCocktail(lst, i, swap_done); + } + } + } while (swap_done); +} + +bool swapItemCocktail(List lst, int i, bool swap_done) { + if (lst[i] > lst[i + 1]) { + swap(lst, i); + swap_done = true; + } + return swap_done; +} + +void swap(List lst, int i) { + int tmp = lst[i]; + lst[i] = lst[i + 1]; + lst[i + 1] = tmp; +} + +void main() //driver function +{ + var lst = [5, 3, 6, 7, 3, 378, 3, 1, -1]; + print(lst); + cocktailSort(lst); + print(lst); +} diff --git a/sort/comb_sort.dart b/sort/comb_sort.dart new file mode 100644 index 00000000..d9cae753 --- /dev/null +++ b/sort/comb_sort.dart @@ -0,0 +1,43 @@ +// function for combsort +void combSort(List list) { + int gpVal = list.length; + double shrink = 1.3; + bool sortedBool = false; + + while (!sortedBool) { + gpVal = (gpVal / shrink).floor(); + if (gpVal > 1) { + sortedBool = false; + } else { + gpVal = 1; + sortedBool = true; + } + + int i = 0; + while (i + gpVal < list.length) { + if (list[i] > list[i + gpVal]) { + swap(list, i, gpVal); + sortedBool = false; + } + i++; + } + } +} + +// function to swap the values +void swap(List list, int i, int gpVal) { + int temp = list[i]; + list[i] = list[i + gpVal]; + list[i + gpVal] = temp; +} + +void main() { + //Get the dummy array + List arr = [1, 451, 562, 2, 99, 78, 5]; + // for printing the array before sorting + print("Before sorting the array: $arr\n"); + // applying combSort function + combSort(arr); + // printing the sortedBool value + print("After sorting the array: $arr"); +} diff --git a/sort/count_sort.dart b/sort/count_sort.dart new file mode 100644 index 00000000..6ead83eb --- /dev/null +++ b/sort/count_sort.dart @@ -0,0 +1,73 @@ +import 'package:test/test.dart'; + +List countSort(List arr) { + // In case the list is empty, return an empty list + if (arr.length == 0) return []; + + int min = arr[0], max = arr[0], i; + List outputArr = [], countArr = []; + for (int i in arr) { + if (i > max) max = i; + if (i < min) min = i; + } + + int range = max - min + 1; + + // INITIALISING countArr with 0's + for (i = 0; i < range; i++) { + countArr.add(0); + } + for (i = 0; i < arr.length; i++) { + outputArr.add(0); + } + + for (i in arr) { + countArr[i - min] += 1; + } + + // PREFIX SUM OF countArr + for (i = 1; i < countArr.length; i++) { + countArr[i] += countArr[i - 1]; + } + + // PUTING VALUES IN SORTED ARRAY + for (i in arr) { + int index = countArr[i - min]; + outputArr[index - 1] = i; + countArr[i - min] -= 1; + } + + // COPYING VALUES OF SORTED ARRAY INTO ORIGINAL ARRAY + for (i = 0; i < outputArr.length; i++) { + arr[i] = outputArr[i]; + } + + return arr; +} + +int main() { + test("Sorting of empty list returns empty list", () { + expect(countSort([]), equals([])); + }); + test("Sorting one element list return same list", () { + expect(countSort([1]), equals([1])); + }); + test("Sorting two times doesnt change input", () { + List lst = [5, 7, 1, 10, 54, -1]; + expect(countSort(lst), equals(countSort(countSort(lst)))); + }); + test("Sorting already sorted list returns same list", () { + List lst = [1, 2, 3, 4, 10]; + expect(countSort(lst), equals(lst)); + }); + test("count sort", () { + expect( + countSort([34, -2, 122, 24435, 23, 434, 232, 1323]), + equals([-2, 23, 34, 122, 232, 434, 1323, 24435]), + ); + }); + + print(countSort([-10, -4, 1, 5, 2, -2])); + + return 0; +} diff --git a/sort/gnome_Sort.dart b/sort/gnome_Sort.dart index 0a302fac..52a6e8d5 100644 --- a/sort/gnome_Sort.dart +++ b/sort/gnome_Sort.dart @@ -3,12 +3,11 @@ //Email:stepfencurryxiao@gmail.com //Function sort the array using gnome sort -void gnomeSort(List arr,var n) { - if (arr == null || n == 0) return; +void gnomeSort(List arr, var n) { + if (arr.isEmpty || n == 0) return; int first = 1; int second = 2; - while (first < n) { if (arr[first - 1] <= arr[first]) { first = second; @@ -18,7 +17,7 @@ void gnomeSort(List arr,var n) { arr[first - 1] = arr[first]; arr[first] = temp; first -= 1; - if (first ==0){ + if (first == 0) { first = 1; second = 2; } @@ -26,19 +25,19 @@ void gnomeSort(List arr,var n) { } } -void main(){ +void main() { //Get the array - List arr = [10,34,6,323,7]; - + List arr = [10, 34, 6, 323, 7]; + //Get size of the array int n = arr.length; - - //print the arrary + + //print the array print(arr); - + //Sorting of array using gnome sort - gnomeSort(arr,n); - + gnomeSort(arr, n); + //print the result print("Sorted:\n" + arr.toString()); } diff --git a/sort/heap_Sort.dart b/sort/heap_Sort.dart index a26d9618..8aeb6442 100644 --- a/sort/heap_Sort.dart +++ b/sort/heap_Sort.dart @@ -1,53 +1,51 @@ -void sort(List arr){ +void sort(List arr) { //The length of the list int n = arr.length; - - //Build heap (rearrange arrary) - for(var i = n / 2 - 1; i >= 0; i--){ - heapify(arr,n,i); + + //Build heap (rearrange array) + for (int i = (n / 2 - 1).round(); i >= 0; i--) { + heapify(arr, n, i); } - + // One by one extract an element from heap - for(var i = n - 1; i >= 0; i--){ + for (int i = n - 1; i >= 0; i--) { //Move current root to end var temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; - + //call max heapify on the reduce heap - heapify(arr,i,0); + heapify(arr, i, 0); } } -void heapify(List arr,var n,var i){ +void heapify(List arr, var n, int i) { //Init largest as root var largest = i; //left = 2*i + 1 - var l = 2 * i + 1; + int l = 2 * i + 1; //right = 2*i + 2 var r = 2 * i + 2; - + // If left child is lager than root - if(l < n && arr[l] > arr[largest]) - largest = l; - + if (l < n && arr[l] > arr[largest]) largest = l; + // If right child is larger than largest so far - if(r < n && arr[r] > arr[largest]) - largest = r; - + if (r < n && arr[r] > arr[largest]) largest = r; + // If largest is not root - if(largest != i){ + if (largest != i) { var swap = arr[i]; arr[i] = arr[largest]; arr[largest] = swap; - + //Recursively heapify the affected sub-tree - heapify(arr,n,largest); + heapify(arr, n, largest); } } -void main(){ - List list = [19,48,5,7,99,10]; +void main() { + List list = [19, 48, 5, 7, 99, 10]; sort(list); print(list); } diff --git a/sort/insert_Sort.dart b/sort/insert_Sort.dart index 0dfec3ef..3ca0bec3 100644 --- a/sort/insert_Sort.dart +++ b/sort/insert_Sort.dart @@ -2,8 +2,11 @@ import 'dart:math' show Random; void main() { final seed = 100, rnd = Random(), length = 100; - var list = - List.generate(length, (i) => rnd.nextInt(seed), growable: false); + var list = List.generate( + length, + (i) => rnd.nextInt(seed), + growable: false, + ); print('before sorting:'); print(list); print('----------------------------------------------'); diff --git a/sort/merge_sort.dart b/sort/merge_sort.dart new file mode 100644 index 00000000..522e2c9b --- /dev/null +++ b/sort/merge_sort.dart @@ -0,0 +1,85 @@ +import 'package:test/test.dart'; + +void merge(List list, int lIndex, int mIndex, int rIndex) { + int lSize = mIndex - lIndex + 1; + int rSize = rIndex - mIndex; + + List lList = new List.filled(lSize, () => 0); + List rList = new List.filled(rSize, () => 0); + + for (int i = 0; i < lSize; i++) lList[i] = list[lIndex + i]; + for (int j = 0; j < rSize; j++) rList[j] = list[mIndex + j + 1]; + + int i = 0, j = 0; + int k = lIndex; + + while (i < lSize && j < rSize) { + if (lList[i] <= rList[j]) { + list[k] = lList[i]; + i++; + } else { + list[k] = rList[j]; + j++; + } + k++; + } + + while (i < lSize) { + list[k] = lList[i]; + i++; + k++; + } + + while (j < rSize) { + list[k] = rList[j]; + j++; + k++; + } +} + +List mergeSort(List list, int lIndex, int rIndex) { + if (lIndex < rIndex) { + int mIndex = (rIndex + lIndex) ~/ 2; // finds the middle index + + mergeSort(list, lIndex, mIndex); // sorts the first half of the list + mergeSort(list, mIndex + 1, rIndex); // sorts the second half of the list + + merge(list, lIndex, mIndex, rIndex); + } + return list; +} + +void main() { + List list = [5, 4, 3, 2, 1]; + test( + 'test case 1', + () => expect(mergeSort(list, 0, list.length - 1), [1, 2, 3, 4, 5]), + ); + + List list1 = []; + test('test case 2', () => expect(mergeSort(list1, 0, list1.length - 1), [])); + + List list2 = [1, 1, 1, 1, 1]; + test( + 'test case 3', + () => expect(mergeSort(list2, 0, list2.length - 1), [1, 1, 1, 1, 1]), + ); + + List list3 = [-1, -11, -1221, -123121, -1111111]; + test( + 'test case 4', + () => expect(mergeSort(list3, 0, list3.length - 1), [ + -1111111, + -123121, + -1221, + -11, + -1, + ]), + ); + + List list4 = [11, 1, 1200, -1, 5]; + test( + 'test case 1', + () => expect(mergeSort(list4, 0, list4.length - 1), [-1, 1, 5, 11, 1200]), + ); +} diff --git a/sort/pigeonhole_sort.dart b/sort/pigeonhole_sort.dart new file mode 100644 index 00000000..adf562dd --- /dev/null +++ b/sort/pigeonhole_sort.dart @@ -0,0 +1,63 @@ +import 'package:test/test.dart'; + +void pigeonholeSort(List arr) { + //The length of the list + int n = arr.length; + + //checking the size + if (n <= 0) { + return; + } + + //Find minimum and maximum values in arr + int min = arr[0]; + int max = arr[0]; + + for (int i = 1; i < n; i++) { + if (arr[i] < min) min = arr[i]; + if (arr[i] > max) max = arr[i]; + } + + int range = max - min; + range++; + + List phole = List.generate(range, (i) => 0); + + //Populate the pigeonholes. + for (int i = 0; i < n; i++) { + phole[arr[i] - min]; + phole[arr[i] - min] = phole[arr[i] - min] + 1; + } + + //Put the elements back into the array in order + int index = 0; + + for (int j = 0; j < range; j++) while (phole[j]-- > 0) arr[index++] = j + min; +} + +void main() { + test("Sort empty list returns empty list", () { + List list = []; + pigeonholeSort(list); + expect(list, isEmpty); + }); + + test("Already sorted list remain sorted", () { + List list = [1, 2, 3, 4, 5]; + pigeonholeSort(list); + expect(list, equals([1, 2, 3, 4, 5])); + }); + + test("Sort", () { + List list = [87, 48, 5, 7, 135, 85]; + pigeonholeSort(list); + expect(list, equals([5, 7, 48, 85, 87, 135])); + }); + + test("Sorted list size doesnt change", () { + List list = [1, 1, 4, 1, -12, -12, 77]; + pigeonholeSort(list); + expect(list.length, equals(7)); + expect(list, [-12, -12, 1, 1, 1, 4, 77]); + }); +} diff --git a/sort/quick_Sort.dart b/sort/quick_Sort.dart index 891432dc..055a866c 100644 --- a/sort/quick_Sort.dart +++ b/sort/quick_Sort.dart @@ -3,7 +3,7 @@ import 'dart:math' show Random; // quickSort // O(n*log n) void main() { - var list = List(); + var list = []; Random random = new Random(); for (var i = 0; i < 100; i++) { list.add(random.nextInt(100)); diff --git a/sort/radix_sort.dart b/sort/radix_sort.dart new file mode 100644 index 00000000..52d55d45 --- /dev/null +++ b/sort/radix_sort.dart @@ -0,0 +1,80 @@ +//radix sort +/* + radix sort is a non-comparative sorting algorithm. It avoids comparison by creating and distributing elements into buckets according to their radix. + For elements with more than one significant digit, this bucketing process is repeated for each digit, + while preserving the ordering of the prior step, until all digits have been considered. For this reason, + radix sort has also been called bucket sort and digital sort. + */ +import 'dart:math' as Math; +import 'dart:math' show Random; +import 'package:test/test.dart'; + +main() { + test("Sorting of empty list returns empty list", () { + expect(radixSort([]), equals([])); + }); + test("Sorting one element list return same list", () { + expect(radixSort([1]), equals([1])); + }); + test("Sorting two times doesnt change input", () { + List lst = [5, 7, 1, 10, 54, -1]; + expect(radixSort(lst), equals(radixSort(radixSort(lst)))); + }); + test("Sorting already sorted list returns same list", () { + List lst = [1, 2, 3, 4, 10]; + expect(radixSort(lst), equals(lst)); + }); + test("radix sort", () { + expect( + radixSort([34, -2, 122, 24435, 23, 434, 232, 1323]), + equals([-2, 23, 34, 122, 232, 434, 1323, 24435]), + ); + }); + + final seed = 10, rnd = Random(), length = 10; + var list = List.generate( + length, + (i) => rnd.nextInt(seed), + growable: false, + ); + print('before sorting:'); + print(list); + print('----------------------------------------------'); + print('After sorting:'); + print(radixSort(list)); +} + +getDigitNum(int n, int i) { + var cal = (n.round().abs() / Math.pow(10, i)) % 10; + + return cal.round(); +} + +digitCount(int number) { + if (number == 0) { + return 1; + } + return (number.abs().toString().length); +} + +mostDigits(List number) { + var maxDigits = 0; + for (var i = 0; i < number.length; i++) { + maxDigits = Math.max(maxDigits, digitCount(number[i])); + } + return maxDigits; +} + +radixSort(List nums) { + var maxDightCount = mostDigits(nums); + for (var k = 0; k < maxDightCount; k++) { + var digitBuckets = List.generate(10, (_) => []); + for (var i = 0; i < nums.length; i++) { + var digit = getDigitNum(nums[i], k); + digitBuckets[digit].add(nums[i]); + } + + nums = digitBuckets.expand((lst) => lst).toList(); + } + return nums; +} diff --git a/sort/select_Sort.dart b/sort/select_Sort.dart index dd766542..4a1161a9 100644 --- a/sort/select_Sort.dart +++ b/sort/select_Sort.dart @@ -3,8 +3,11 @@ import 'dart:math' show Random; //main function,the program start void main() { final seed = 100, rnd = Random(), length = 100; - var list = - List.generate(length, (i) => rnd.nextInt(seed), growable: false); + var list = List.generate( + length, + (i) => rnd.nextInt(seed), + growable: false, + ); print('before sorting:'); print(list); print('--------------------------------------'); diff --git a/sort/shell_Sort.dart b/sort/shell_Sort.dart index c4f93cc8..6d5275d1 100644 --- a/sort/shell_Sort.dart +++ b/sort/shell_Sort.dart @@ -2,8 +2,11 @@ import 'dart:math' show Random; void main() { final seed = 100, rnd = Random(), length = 100; - var list = - List.generate(length, (i) => rnd.nextInt(seed), growable: false); + var list = List.generate( + length, + (i) => rnd.nextInt(seed), + growable: false, + ); print('before sorting:'); print(list); print('----------------------------------------------'); diff --git a/sort/tim_Sort.dart b/sort/tim_Sort.dart index f8de1610..d2593d81 100644 --- a/sort/tim_Sort.dart +++ b/sort/tim_Sort.dart @@ -1,32 +1,36 @@ import 'dart:math'; + +import 'package:test/expect.dart'; +import 'package:test/scaffolding.dart'; + const int RUN = 32; -void insertionSort(List list, int left, int right) -{ +void insertionSort(List list, int left, int right) { for (int i = left + 1; i <= right; i++) { int temp = list[i]; int j = i - 1; while (j >= left && list[j] > temp) { - list[j+1] = list[j]; + list[j + 1] = list[j]; j--; } - list[j+1] = temp; + list[j + 1] = temp; } } void merge(List list, int left, int middle, int right) { int length1 = middle - left + 1, length2 = right - middle; - List leftList = new List(length1), rightList = new List(length2); + List leftList = List.filled(length1, null), + rightList = new List.filled(length2, null); - for(int i = 0; i < length1; i++) { + for (int i = 0; i < length1; i++) { leftList[i] = list[left + i]; } - for(int i = 0; i sMap = {}; + Map tMap = {}; + + for (int i = 0; i < string1.length; ++i) { + String s = string1[i]; + String c = string2[i]; + + // Both characters are not mapped so far. + if (!sMap.containsKey(s) && !tMap.containsKey(c)) { + sMap[s] = c; + tMap[c] = s; + } + // One of the characters is mapped. + else if (!sMap.containsKey(s) || !tMap.containsKey(c)) { + return false; + } + // Both characters are mapped + else if (sMap[s] != c || tMap[c] != s) { + return false; + } + } + return true; +} + +void main() { + test('test case 1', () => expect(isIsomorphic('egg', 'add'), true)); + test('test case 2', () => expect(isIsomorphic('foo', 'bar'), false)); + test('test case 3', () => expect(isIsomorphic('paper', 'title'), true)); +} diff --git a/strings/knuth_morris_prat.dart b/strings/knuth_morris_prat.dart new file mode 100644 index 00000000..2841bdb3 --- /dev/null +++ b/strings/knuth_morris_prat.dart @@ -0,0 +1,103 @@ +import 'package:test/test.dart'; + +/// Preprocess pattern to identify any suffixes that are identical to prefixes +/// in the given string. +/// +/// Build a pattern which tells us where to continue iteration from if we +/// get a mismatch between the character +/// +/// Step through the text one character at a time and compare it to a character in +/// the pattern updating our location within the pattern if necessary +bool stringCompare(String string, String subString) { + if (subString.isEmpty) { + return false; + } + + List pattern = new List.generate( + subString.length, + (int index) => -1, + ); + + int i = 1; + int j = 0; + + while (i < subString.length) { + if (subString[i] == subString[j]) { + pattern[i] = j; + i++; + j++; + } else if (j > 0) { + j = pattern[j - 1] + 1; + } else { + i++; + } + } + + return stringCompareHelper(string, subString, pattern); +} + +bool stringCompareHelper(String string, String subString, List pattern) { + int i = 0; + int j = 0; + + while (i + subString.length - j <= string.length) { + if (string[i] == subString[j]) { + if (j == subString.length - 1) { + return true; + } + i++; + j++; + } else if (j > 0) { + j = pattern[j - 1] + 1; + } else { + i++; + } + } + return false; +} + +void main() { + String string; + String subString; + + test(('KMP: '), () { + string = 'aefoaefcdaefcdaed'; + subString = 'aefcdaed'; + expect(stringCompare(string, subString), isTrue); + }); + + test(('KMP: '), () { + string = 'testwafwafawfawfawfawfawfawfawfa'; + subString = 'fawfawfawfawfa'; + expect(stringCompare(string, subString), isTrue); + }); + + test(('KMP: '), () { + string = 'aabc'; + subString = 'abc'; + expect(stringCompare(string, subString), isTrue); + }); + + test(('KMP: '), () { + string = 'adafccfefbbbfeeccbcfd'; + subString = 'ecb'; + expect(stringCompare(string, subString), isFalse); + }); + + test(('KMP: '), () { + string = 'akash'; + subString = 'christy'; + expect(stringCompare(string, subString), isFalse); + }); + test(('KMP: '), () { + string = ''; + subString = 'asd'; + expect(stringCompare(string, subString), isFalse); + }); + + test(('KMP: '), () { + string = 'asd'; + subString = ''; + expect(stringCompare(string, subString), isFalse); + }); +} diff --git a/strings/remove duplicates.dart b/strings/remove duplicates.dart new file mode 100644 index 00000000..839f77c4 --- /dev/null +++ b/strings/remove duplicates.dart @@ -0,0 +1,33 @@ +import 'package:test/test.dart'; + +// function to remove duplicate in string +String removeDups(String s) { + var arr = new List.filled(256, 0); + String l = ''; + int i = 0; + for (i = 0; i < s.length; i++) { + if (arr[s.codeUnitAt(i)] == 0) { + l += s[i]; + arr[s.codeUnitAt(i)]++; + } + } + return l; +} + +void main() { + test("removeDups from string without duplicates returns same string", () { + expect(removeDups("1234"), equals("1234")); + }); + + test("removeDups from empty list returns empty list", () { + expect(removeDups(""), equals("")); + }); + + test("removeDups from 12341234 returns 1234", () { + expect(removeDups("12341234"), equals("1234")); + }); + + test("removeDups from aaaab returns ab", () { + expect(removeDups("aaaab"), equals("ab")); + }); +} diff --git a/strings/reverse_string.dart b/strings/reverse_string.dart new file mode 100644 index 00000000..7248acab --- /dev/null +++ b/strings/reverse_string.dart @@ -0,0 +1,25 @@ +/** + * Reverse String + */ + +void main() { + String stringToReverse = "The Algorithms:Dart"; + print('Method 1 => $stringToReverse\t ${reverseString(stringToReverse)}'); + print('Method 2 => $stringToReverse\t ${reverseString2(stringToReverse)}'); +} + +/** + * * easiest way to reverses the string + */ +String reverseString(String str) { + return str.split('').reversed.join(); +} + +/** + * Second way to reverses the string + */ +String reverseString2(String str) { + String reversed = ""; + for (int i = str.length - 1; i >= 0; i--) reversed += str[i]; + return reversed; +} diff --git a/strings/reverse_words_of_string.dart b/strings/reverse_words_of_string.dart new file mode 100644 index 00000000..4b73b5fc --- /dev/null +++ b/strings/reverse_words_of_string.dart @@ -0,0 +1,42 @@ +import 'package:test/test.dart'; + +String reverseStringWords(String s) { + String res = ""; + int m = s.length; + int j = m - 1; + for (int i = m - 1; i >= 0; i--) { + if (s[i] == '.') { + for (int j1 = i + 1; j1 <= j; j1++) { + res += s[j1]; + } + res += s[i]; + j = i - 1; + } else if (i == 0) { + for (int j1 = i; j1 <= j; j1++) { + res += s[j1]; + } + } + } + return res; +} + +void main() { + test("reverseStringWords single word returns same word", () { + expect(reverseStringWords("word"), equals("word")); + }); + + test("reverseStringWords w1.w2 returns w2.w1", () { + expect(reverseStringWords("w1.w2"), equals("w2.w1")); + }); + + test("reverseStringWords on empty string returns empty string", () { + expect(reverseStringWords(""), equals("")); + }); + + test("reverseStringWords", () { + expect( + reverseStringWords("abhishek.is.a.good.boy"), + equals("boy.good.a.is.abhishek"), + ); + }); +} diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000..dfe2938a --- /dev/null +++ b/tests/README.md @@ -0,0 +1 @@ +# Put dart test files here... diff --git a/trees/path_sum.dart b/trees/path_sum.dart new file mode 100644 index 00000000..a601ff0e --- /dev/null +++ b/trees/path_sum.dart @@ -0,0 +1,49 @@ +import 'package:test/test.dart'; + +// Question URL: https://leetcode.com/problems/path-sum/description/ +class TreeNode { + int val; + TreeNode? left; + TreeNode? right; + TreeNode([this.val = 0, this.left, this.right]); +} + +bool isLeaf(TreeNode node) { + if (node.left == null && node.right == null) { + return true; + } + return false; +} + +bool traverse(TreeNode? node, int targetSum, int runningSum) { + if (node == null) { + return false; + } + runningSum += node.val; + if (isLeaf(node) && runningSum == targetSum) { + return true; + } + + bool hasPathSumInLeftTree = traverse(node.left, targetSum, runningSum); + bool hasPathSumInRightTree = traverse(node.right, targetSum, runningSum); + return hasPathSumInLeftTree || hasPathSumInRightTree; +} + +bool hasPathSum(TreeNode root, int targetSum) { + return traverse(root, targetSum, 0); +} + +void main() { + TreeNode root = TreeNode( + 5, + TreeNode(4, TreeNode(11, TreeNode(7), TreeNode(2))), + TreeNode(8, TreeNode(13), TreeNode(4, null, TreeNode(1))), + ); + + test('Test Case 1: true case', () { + expect(hasPathSum(root, 22), true); + }); + test('Test Case 2: false case', () { + expect(hasPathSum(root, 222), false); + }); +}