├── .github └── workflows │ ├── markdown-link-check.json │ └── markdown-link-check.yml ├── LICENSE ├── README.md ├── media └── algorithms_data_structures.jpg └── src └── functional-recursion ├── .formatter.exs ├── .gitignore ├── .vscode └── launch.json ├── README.md ├── lib ├── fibonacci.ex ├── math_operations.ex └── parentheses.ex ├── mix.exs ├── mix.lock └── test ├── fibonacci_test.exs ├── math_operations_test.exs ├── parentheses_test.exs └── test_helper.exs /.github/workflows/markdown-link-check.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": [ 3 | { 4 | "pattern": "^https://leetcode.com/" 5 | } 6 | ], 7 | "aliveStatusCodes": [429, 200] 8 | } 9 | -------------------------------------------------------------------------------- /.github/workflows/markdown-link-check.yml: -------------------------------------------------------------------------------- 1 | name: 'Check Markdown links' 2 | 3 | 4 | on: 5 | workflow_dispatch: # To can dispatch manually 6 | 7 | # Schedule to run every week on Sunday at 00:00 UTC 8 | schedule: 9 | - cron: '0 0 * * 0' 10 | 11 | push: 12 | branches: 13 | - main 14 | 15 | pull_request: 16 | types: [opened, reopened, edited, synchronize] 17 | branches: 18 | - main 19 | 20 | 21 | jobs: 22 | markdown-link-check: 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - name: "Checkout" 27 | uses: actions/checkout@v4 28 | 29 | - name: 'Readme analysis' 30 | uses: gaurav-nelson/github-action-markdown-link-check@v1 31 | with: 32 | use-verbose-mode: 'yes' 33 | base-branch: 'main' 34 | config-file: '.github/workflows/markdown-link-check.json' 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Craft & Code Club 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithms & Data Structures - From Zero to Hero 2 | 3 | ![Algorithms & Data Structures - From Zero to Hero](./media/algorithms_data_structures.jpg) 4 | 5 | Este repositório é destinado a serie da nossa comunidade **Craft & Code Club** sobre **Algorithms & Data Structures - From Zero to Hero**. 6 | 7 | Vamos usar este repositorio para compartilhar o roadmap, códigos, slides e materiais de apoio aos nossos encontros. 8 | 9 | ## Sobre a série 10 | 11 | - [YouTube Playlist](https://www.youtube.com/watch?v=MtLv9Rwb55Q&list=PLl10TyPY67Jgbh4QdRlRKr-7PjB9i5hWg) 12 | - [Meetup](https://www.meetup.com/craft-code-club/events/) 13 | 14 | ## Contrubuições 15 | 16 | Todas as contribuições são bem-vindas. 17 | 18 | - Se tens alguma sugestão ou correção, por favor, abra uma issue deste repositório. 19 | - Se encontraste algum erro ou algo que possa ser melhorado, por favor, abra um pull request. 20 | 21 | ## Roadmap 22 | 23 | ```mermaid 24 | flowchart 25 | BigO[Big O Notation] --> Arrays-Topic 26 | 27 | subgraph Arrays-Topic[Arrays] 28 | direction TB 29 | Arrays --> BinarySearchBasic["Binary Search (Basic)"] 30 | end 31 | 32 | BinarySearchBasic --> Strings 33 | Strings --> BubbleSort 34 | 35 | subgraph BasicSorting-Topic["Sorting (Basic)"] 36 | direction TB 37 | BubbleSort(Bubble Sort) 38 | --> InsertionSort[Insertion Sort] 39 | --> SelectionSort[Selection Sort] 40 | end 41 | 42 | BasicSorting-Topic --> LinkedList-Topic 43 | 44 | subgraph LinkedList-Topic[Linked List] 45 | direction TB 46 | DoublyLinkedList[Doubly Linked List] 47 | Sentinels 48 | FastSlow[Fast and Slow] 49 | DummyNodePointer["Dummy node (pointer)"] 50 | IdentifyCycles[Identify Cycles] 51 | FloydCycle[Floyd Cycle] 52 | end 53 | 54 | LinkedList-Topic 55 | --> BinarySearchDeep["Binary Search (Deep)"] 56 | --> TwoPointers[Two Pointers] 57 | --> SlidingWindow[Sliding Window] 58 | --> PrefixSum[Prefix Sum] 59 | --> HashMapSet-Topic 60 | 61 | subgraph HashMapSet-Topic[Hash Map / Set] 62 | HashMapSet-ColisionResolution["Colision resolution (Buckets / Open Adrress)"] 63 | CounterFrequency[Counter / Frequency] 64 | end 65 | 66 | HashMapSet-Topic 67 | --> Stack 68 | --> Recursion-Topic 69 | 70 | subgraph Recursion-Topic[Recursion] 71 | direction TB 72 | FunctionalProgramming[Functional Programming] 73 | ReverseLinkedList[Reverse LinkedList] 74 | Fibonnacci 75 | PowerOf[Power of 2/3/4] 76 | end 77 | 78 | Recursion-Topic 79 | --> Queue 80 | --> Trees 81 | 82 | subgraph Trees-Topic[Trees] 83 | direction TB 84 | Trees 85 | --> BinaryTree[Binary Tree] 86 | --> DFS-Topic 87 | --> BFS-Topic 88 | --> KAry[K-ary] 89 | --> BinarySearchTree[Binary Search Tree] 90 | 91 | subgraph DFS-Topic[DFS] 92 | direction LR 93 | DFS --> DFS-Recursion[Recursion] 94 | DFS --> DFS-Stack[Stack] 95 | DFS --> DFS-PreOrder[Pre Order] 96 | DFS --> DFS-InOrder[In Order] 97 | DFS --> DFS-PostOrder[Post Order] 98 | DFS --> DFS-Boundary[Boundary] 99 | DFS --> DFS-Diagonal[Diagonal] 100 | end 101 | 102 | subgraph BFS-Topic[BFS] 103 | direction TB 104 | BFS --> BFS-Queue[Queue] 105 | end 106 | 107 | end 108 | 109 | BinarySearchTree 110 | --> BinaryHeap[Binary Heap] 111 | --> HeapSort 112 | 113 | subgraph MediumSorting-Topic["Sorting (Medium)"] 114 | direction TB 115 | HeapSort(Heap Sort) 116 | --> MergeSort[Merge Sort] 117 | --> ShellSort[Shell Sort] 118 | --> QuickSort[Quick Sort] 119 | end 120 | 121 | QuickSort --> Graphs 122 | 123 | subgraph Graphs-Topic[Graphs] 124 | direction LR 125 | Graphs 126 | --> Graphs-DFSBFS[DFS / BFS] 127 | --> Dijkstra 128 | 129 | subgraph SSSP-Topic[SSSP] 130 | Dijkstra 131 | --> Bellman-Ford 132 | --> A-Star 133 | end 134 | 135 | A-Star --> FloydWarshall 136 | 137 | subgraph APSP-Topic[APSP] 138 | FloydWarshall[Floyd Warshall] 139 | end 140 | end 141 | 142 | FloydWarshall 143 | --> TopologicalSorting[Topological Sorting] 144 | --> Backtracking 145 | --> Top-Down 146 | --> Memoization 147 | --> Botton-Up 148 | --> Tabulation 149 | --> DynamicPrograming 150 | 151 | subgraph DynamicPrograming-Topic[Dynamic Programing] 152 | direction TB 153 | DynamicPrograming[Dynamic Programing] 154 | --> DynamicPrograming-1D[1D] 155 | --> DynamicPrograming-Multidimensional[Multidimensional] 156 | end 157 | 158 | DynamicPrograming-Multidimensional --> BitManipulation-Base-2-8-16 159 | 160 | subgraph BitManipulation-Topic[Bit Manipulation] 161 | direction TB 162 | BitManipulation-Base-2-8-16[Base 2 / Base 8 / Base 16] 163 | --> BitManipulation-Complement[Complement] 164 | --> BitManipulation-Shift[Bit Shift Left and Right] 165 | --> BitManipulation-Operations[And / Or / Xor] 166 | end 167 | 168 | BitManipulation-Operations --> CountingSort 169 | 170 | subgraph AdvancedSorting-Topic["Sorting (Advanced)"] 171 | direction TB 172 | CountingSort[Counting Sort] 173 | --> RadixSort[Radix Sort] 174 | --> BucketSort[Bucket Sort] 175 | end 176 | 177 | BucketSort 178 | --> Trie 179 | --> Intervals 180 | --> Greedy 181 | --> AdvancedGraphs["Graphs (Advanced)"] 182 | --> MathGeometry["Math & Geometry"] 183 | ``` 184 | 185 | 186 | 187 | - [x] **Big O Notation - Análise Assintótica de Algoritmos** 188 | - [Youtube - Encontro](https://www.youtube.com/watch?v=MtLv9Rwb55Q) 189 | 190 | 191 | - [x] **Arrays** 192 | - [Youtube - Encontro](https://www.youtube.com/watch?v=c95xvXCU34A) 193 | 194 | 195 | - [x] **Strings** 196 | - [Youtube - Encontro](https://www.youtube.com/watch?v=B9CCEwjoXBk) 197 | 198 | 199 | - [x] **Algoritmos de Ordenação Básicos** 200 | - [Youtube - Encontro](https://www.youtube.com/watch?v=GxhxsbbzaTI) 201 | - Topicos: 202 | - [Bubble Sort](https://github.com/NelsonBN/algorithms-data-structures-bubble-sort) 203 | - [Insertion Sort](https://github.com/NelsonBN/algorithms-data-structures-insertion-sort) 204 | - [Selection Sort](https://github.com/NelsonBN/algorithms-data-structures-insertion-sort) 205 | 206 | 207 | - [x] **Linked Lists** 208 | - [Youtube - Encontro](https://www.youtube.com/watch?v=j0E5hJZ__EA) 209 | - Topicos: 210 | - [Singly Linked List](https://github.com/NelsonBN/algorithms-data-structures-linked-list/blob/main/src/singly_linked_list.py) 211 | - [Operations](https://github.com/NelsonBN/algorithms-data-structures-linked-list/blob/main/src/singly_linked_list_operations.py) 212 | - [Operations Optimized](https://github.com/NelsonBN/algorithms-data-structures-linked-list/blob/main/src/singly_linked_list_operations_optimized.py) 213 | - Doubly Linked List 214 | - Sentinels 215 | - Dummy node (pointer) 216 | - [Rotate Linked List](https://github.com/NelsonBN/algorithms-data-structures-linked-list/blob/main/src/rotate_linked_list.py) 217 | - [Visualização](https://github.com/NelsonBN/algorithms-data-structures-linked-list/raw/main/media/reversing_linked_list.webp) 218 | - [Fast and Slow Pointer](https://github.com/NelsonBN/algorithms-data-structures-linked-list/blob/main/src/fast_and_slow_pointer.py) 219 | - [Identify Cycles](https://github.com/NelsonBN/algorithms-data-structures-linked-list/blob/main/src/identifying_cycles.py) 220 | - [Floyd Cycle](https://github.com/NelsonBN/algorithms-data-structures-linked-list/blob/main/src/floyd_cycle.py) 221 | 222 | 223 | - [x] **Binary Search** 224 | - [Youtube - Encontro](https://www.youtube.com/watch?v=62ZGcXDpbys) 225 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-binary-search) 226 | 227 | 228 | - [x] **Two Pointers** 229 | - [Youtube - Encontro](https://www.youtube.com/watch?v=a1QMdXgcQwY) 230 | 231 | 232 | - [x] **Sliding Window** 233 | - [Youtube - Encontro](https://www.youtube.com/watch?v=OvIJw1AMNzI) 234 | - Exercicios: 235 | - Fixed Window -> [1343. Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold](https://leetcode.com/problems/number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold/description/) 236 | 237 | 238 | - [x] **Prefix Sum** 239 | - [Youtube - Encontro](https://www.youtube.com/watch?v=yMnLofkS7DM) 240 | 241 | 242 | - [x] **Hash Map / Set** 243 | - [Youtube - Encontro](https://www.youtube.com/watch?v=JFhdCBrKTX0) 244 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-hashtable) 245 | 246 | 247 | - [x] **Stack** 248 | - [Youtube - Encontro](https://www.youtube.com/watch?v=JRbrNgsYuT0) 249 | - [Demo](https://github.com/matheusses/dsa/tree/main/src/stack) 250 | - Exercicios: 251 | - [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/description/) 252 | - [1544. Make The String Great](https://leetcode.com/problems/make-the-string-great/description/) 253 | 254 | 255 | - [x] **Recursividade** 256 | - Fundamentos 257 | - [Youtube - Encontro](https://www.youtube.com/watch?v=KkSAaQHCkSE) 258 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-recursion) 259 | - Paradigma Funcional 260 | - [Youtube - Encontro](https://www.youtube.com/watch?v=rbEYjJdaIZI) 261 | - [Demo](./src/functional-recursion/README.md) 262 | 263 | 264 | - [x] **Queue** 265 | - [Youtube - Encontro](https://www.youtube.com/watch?v=KJaVKLZsMcg) 266 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-queue) 267 | - Exercicios: 268 | - [232. Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/description/) 269 | 270 | 271 | - [x] **Tree** 272 | - [Youtube - Encontro](https://www.youtube.com/watch?v=OAcm2rXqz9M) 273 | 274 | 275 | - [x] **Tree Traverse** 276 | - [Youtube - Encontro](https://www.youtube.com/watch?v=_-2F65OVWjo) 277 | - [Code Implementation examples in Go](https://github.com/giovannymassuia/DS-A/tree/main/go-dsa/tree) 278 | 279 | 280 | - [x] **k-ary tree** 281 | - [Youtube - Encontro](https://www.youtube.com/watch?v=FLZxMQFTqvY) 282 | - [Code Implementation examples in Go](https://github.com/giovannymassuia/DS-A/tree/main/go-dsa/tree/k_ary) 283 | 284 | 285 | - [x] **Binary Search Tree** 286 | - [Youtube - Encontro](https://www.youtube.com/watch?v=CITquySB4ls) 287 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-binary-search-tree) 288 | - [Playground](https://www.cs.usfca.edu/~galles/visualization/BST.html) 289 | 290 | 291 | - [x] **Binary Heap** 292 | - [Youtube - Encontro](https://www.youtube.com/watch?v=HVWw20nOLHk) 293 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-binary-heap) 294 | 295 | 296 | - [x] **Algoritmos de Ordenação Básicos - Heap Sort** 297 | - [Youtube - Encontro](https://www.youtube.com/watch?v=wUfOyKMjamM) 298 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-heap-sort) 299 | 300 | 301 | - [ ] **Algoritmos de Ordenação Básicos - Merge Sort** 302 | - [Youtube - Encontro](https://www.youtube.com/watch?v=lbktBOwmmhg) 303 | - [Demo - Merge Sort](https://github.com/NelsonBN/algorithms-data-structures-merge-sort) 304 | - [Demo - Stable Vs. Unstable Sorting Algorithms](https://github.com/NelsonBN/algorithms-data-structures-stable-vs-unstable-sort-algos) 305 | 306 | 307 | - [x] **Algoritmos de Ordenação Básicos - Shell Sort** 308 | - [Youtube - Encontro](https://www.youtube.com/watch?v=symbT7Cgrr8) 309 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-shell-sort) 310 | 311 | 312 | - [x] **Algoritmos de Ordenação Básicos - Quick Sort** 313 | - [Youtube - Encontro](https://www.youtube.com/watch?v=2T0Itw-oaEA) 314 | - [Demo](https://github.com/NelsonBN/algorithms-data-structures-quick-sort) 315 | 316 | 317 | - [x] **Algoritmos de Ordenação Básicos - Introdução a Grafos** 318 | - [Youtube - Encontro - Part I](https://www.youtube.com/watch?v=cILrU-dtuEc) 319 | - [Youtube - Encontro - Part II](https://www.youtube.com/watch?v=IP0C0qCYWIc) 320 | 321 | 322 | - [ ] **...** 323 | 324 | ## Status 325 | 326 | ![Links](https://github.com/craft-code-club/algorithms-data-structures-from-zero-to-hero/actions/workflows/markdown-link-check.yml/badge.svg) 327 | -------------------------------------------------------------------------------- /media/algorithms_data_structures.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craft-code-club/algorithms-data-structures-from-zero-to-hero/5e2723a57c14ed6347c216b89224424469a6c41d/media/algorithms_data_structures.jpg -------------------------------------------------------------------------------- /src/functional-recursion/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /src/functional-recursion/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | fibonacci-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /src/functional-recursion/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "mix_task", 9 | "name": "mix (Default task)", 10 | "request": "launch", 11 | "projectDir": "${workspaceRoot}" 12 | }, 13 | { 14 | "type": "mix_task", 15 | "name": "mix test", 16 | "request": "launch", 17 | "task": "test", 18 | "taskArgs": [ 19 | "--trace" 20 | ], 21 | "startApps": true, 22 | "projectDir": "${workspaceRoot}", 23 | "requireFiles": [ 24 | "test/**/test_helper.exs", 25 | "test/**/*_test.exs" 26 | ] 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /src/functional-recursion/README.md: -------------------------------------------------------------------------------- 1 | # Fibonacci 2 | 3 | **TODO: Add description** 4 | 5 | ## Installation 6 | 7 | 1. **Download and install Erlang:** 8 | 9 | Go to the [Erlang Downloads page](https://www.erlang.org/downloads) and download the installer for Windows. Run the installer and follow the on-screen instructions. 10 | 11 | 2. **Download and install Elixir:** 12 | 13 | Go to the [Elixir Downloads page](https://elixir-lang.org/install.html#windows) and download the installer for Windows. Run the installer and follow the on-screen instructions. 14 | 15 | ## Running the Project 16 | 17 | 1. **Install dependencies:** 18 | 19 | ```bash 20 | mix deps.get 21 | ``` 22 | 23 | 2. **Run the tests:** 24 | 25 | ```bash 26 | mix test 27 | ``` 28 | 29 | Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) 30 | and published on [HexDocs](https://hexdocs.pm). Once published, the docs can 31 | be found at . 32 | 33 | -------------------------------------------------------------------------------- /src/functional-recursion/lib/fibonacci.ex: -------------------------------------------------------------------------------- 1 | defmodule Fibonacci do 2 | @moduledoc """ 3 | Documentation for `Fibonacci`. 4 | """ 5 | 6 | def fib(0), do: 0 7 | def fib(1), do: 1 8 | def fib(n), do: fib(n - 1) + fib(n - 2) 9 | 10 | def fib_tco(n), do: do_fib(n, 0, 1) 11 | defp do_fib(0, a, _), do: a 12 | defp do_fib(1, _, b), do: b 13 | defp do_fib(n, a, b), do: do_fib(n - 1, b, a + b) 14 | end 15 | -------------------------------------------------------------------------------- /src/functional-recursion/lib/math_operations.ex: -------------------------------------------------------------------------------- 1 | defmodule MathOperations do 2 | def print([]) do 3 | IO.puts("Fim da lista") 4 | end 5 | 6 | def print(list) do 7 | head = hd(list) 8 | tail = tl(list) 9 | 10 | IO.puts(head) 11 | print(tail) 12 | end 13 | 14 | def sum_numbers([]) do 15 | 0 16 | end 17 | 18 | def sum_numbers(numbers) do 19 | [head | tail] = numbers 20 | 21 | head + sum_numbers(tail) 22 | end 23 | 24 | def sum_numbers_tr([], sum) do 25 | sum 26 | end 27 | 28 | def sum_numbers_tr(numbers, sum) do 29 | [head | tail] = numbers 30 | 31 | temp_sum = head + sum 32 | sum_numbers_tr(tail, temp_sum) 33 | end 34 | 35 | def double([]) do 36 | [] 37 | end 38 | 39 | def double([head | tail]) do 40 | [head * 2 | double(tail)] 41 | end 42 | 43 | def double_tr(list, list \\ []) 44 | def double_tr([], list), do: Enum.reverse(list) 45 | 46 | def double_tr(numbers, list) do 47 | head = hd(numbers) 48 | tail = tl(numbers) 49 | 50 | double = head * 2 51 | 52 | double_tr(tail, [double | list]) 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /src/functional-recursion/lib/parentheses.ex: -------------------------------------------------------------------------------- 1 | defmodule Parentheses do 2 | def is_parentheses_valid?(text) do 3 | validate_recursive(String.graphemes(text), []) 4 | end 5 | 6 | defp validate_recursive([], []), do: true 7 | 8 | defp validate_recursive([], _stack), do: false 9 | 10 | defp validate_recursive(["(" | tail], stack) do 11 | validate_recursive(tail, [")" | stack]) 12 | end 13 | 14 | defp validate_recursive([")" | tail], [")" | tail_stack]), 15 | do: validate_recursive(tail, tail_stack) 16 | 17 | defp validate_recursive([_ | tail], stack) do 18 | validate_recursive(tail, stack) 19 | end 20 | 21 | def is_parentheses_valid_iterative?(text) do 22 | count = 23 | text 24 | |> String.graphemes() 25 | |> Enum.reduce(0, fn char, count -> 26 | case char do 27 | "(" -> count + 1 28 | ")" -> count - 1 29 | _ -> count 30 | end 31 | end) 32 | 33 | count == 0 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /src/functional-recursion/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Fibonacci.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :fibonacci, 7 | version: "0.1.0", 8 | elixir: "~> 1.16", 9 | start_permanent: Mix.env() == :prod, 10 | deps: deps() 11 | ] 12 | end 13 | 14 | # Run "mix help compile.app" to learn about applications. 15 | def application do 16 | [ 17 | extra_applications: [:logger] 18 | ] 19 | end 20 | 21 | # Run "mix help deps" to learn about dependencies. 22 | defp deps do 23 | [ 24 | {:benchee, "~> 1.3"}, 25 | {:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false}, 26 | # {:dep_from_hexpm, "~> 0.3.0"}, 27 | # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} 28 | ] 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /src/functional-recursion/mix.lock: -------------------------------------------------------------------------------- 1 | %{ 2 | "benchee": {:hex, :benchee, "1.3.0", "f64e3b64ad3563fa9838146ddefb2d2f94cf5b473bdfd63f5ca4d0657bf96694", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "34f4294068c11b2bd2ebf2c59aac9c7da26ffa0068afdf3419f1b176e16c5f81"}, 3 | "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, 4 | "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, 5 | "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, 6 | "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, 7 | } 8 | -------------------------------------------------------------------------------- /src/functional-recursion/test/fibonacci_test.exs: -------------------------------------------------------------------------------- 1 | defmodule FibonacciTest do 2 | use ExUnit.Case 3 | doctest Fibonacci 4 | 5 | test "fibonacci" do 6 | assert Fibonacci.fib(2) == 1 7 | assert Fibonacci.fib(6) == 8 8 | assert Fibonacci.fib(10) == 55 9 | end 10 | 11 | test "fibonacci tail call optimization" do 12 | assert Fibonacci.fib_tco(2) == 1 13 | assert Fibonacci.fib_tco(6) == 8 14 | assert Fibonacci.fib_tco(10) == 55 15 | end 16 | 17 | test "Benchmark" do 18 | n = 20 19 | 20 | Benchee.run( 21 | %{ 22 | "fibonacci" => fn -> Fibonacci.fib(n) end, 23 | "fibonacci with tail-call optimization" => fn -> Fibonacci.fib_tco(n) end 24 | }, 25 | print: [fast_warning: false]) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /src/functional-recursion/test/math_operations_test.exs: -------------------------------------------------------------------------------- 1 | defmodule RecursionTest do 2 | use ExUnit.Case 3 | 4 | test "sum_numbers" do 5 | assert MathOperations.sum_numbers([1, 2, 3, 4]) == 10 6 | assert MathOperations.sum_numbers_tr([1, 2, 3, 4], 0) == 10 7 | end 8 | 9 | test "Sum numbers benchmark" do 10 | array = 0..1000 |> Enum.to_list() 11 | 12 | Benchee.run( 13 | %{ 14 | "Body recursive" => fn -> MathOperations.sum_numbers(array) end, 15 | "Tail recursive" => fn -> MathOperations.sum_numbers_tr(array, 0) end 16 | }, 17 | print: [fast_warning: false] 18 | ) 19 | end 20 | 21 | test "Double numbers in array" do 22 | assert MathOperations.double([1, 2, 3, 4]) == [2, 4, 6, 8] 23 | assert MathOperations.double_tr([1, 2, 3, 4]) == [2, 4, 6, 8] 24 | end 25 | 26 | @tag skip: true 27 | test "Double numbers benchmark" do 28 | array = 0..1000 |> Enum.to_list() 29 | 30 | Benchee.run( 31 | %{ 32 | "Body recursive" => fn -> MathOperations.double(array) end, 33 | "Tail recursive" => fn -> MathOperations.double_tr(array) end 34 | }, 35 | print: [fast_warning: false] 36 | ) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /src/functional-recursion/test/parentheses_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ParenthesesTest do 2 | use ExUnit.Case 3 | 4 | test "Validate parentheses recursive" do 5 | assert Parentheses.is_parentheses_valid?("(text)") == true 6 | assert Parentheses.is_parentheses_valid?("((text))") == true 7 | assert Parentheses.is_parentheses_valid?("()()") == true 8 | assert Parentheses.is_parentheses_valid?("(text") == false 9 | assert Parentheses.is_parentheses_valid?("(text)(") == false 10 | assert Parentheses.is_parentheses_valid?("((text") == false 11 | end 12 | 13 | test "Validate parentheses iterative" do 14 | assert Parentheses.is_parentheses_valid_iterative?("(text)") == true 15 | assert Parentheses.is_parentheses_valid_iterative?("((text))") == true 16 | assert Parentheses.is_parentheses_valid_iterative?("()()") == true 17 | assert Parentheses.is_parentheses_valid_iterative?("(text") == false 18 | assert Parentheses.is_parentheses_valid_iterative?("(text)(") == false 19 | assert Parentheses.is_parentheses_valid_iterative?("((text") == false 20 | end 21 | 22 | @tag skip: true 23 | test "Validate parentheses benchmark" do 24 | inputs = %{ 25 | "case single pair valid" => "(text)", 26 | "case double pair valid" => "((text))", 27 | "case long text valid" => "(fdsfsfddsfsdfsdfsfsdfddsdfddddsdfsfsdfsdfsdfsdfsdfdsf)", 28 | "case long text invalid" => "fdsdfsfddsfsdfsdfsfsdfddsdfddddsdfsfsdfsdfsdfsdfsdfdsf)" 29 | } 30 | 31 | Benchee.run( 32 | %{ 33 | "Recursive" => fn input -> Parentheses.is_parentheses_valid?(input) end, 34 | "Iterative" => fn input -> Parentheses.is_parentheses_valid_iterative?(input) end 35 | }, 36 | inputs: inputs, 37 | print: [fast_warning: false]) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /src/functional-recursion/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | --------------------------------------------------------------------------------