├── .clang-format ├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── README.pt-br.md ├── cryptography └── caesar-cipher │ ├── README.md │ ├── README.pt-br.md │ └── c │ ├── Makefile │ └── main.c ├── data-structures ├── avl-tree │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c ├── binary-heap │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── java │ │ ├── BinaryHeap.java │ │ ├── Makefile │ │ ├── MaxHeap.java │ │ ├── MedianHeap.java │ │ └── MinHeap.java ├── binary-search-tree │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── java │ │ ├── BinaryTree.java │ │ └── Makefile ├── disjoint-set │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── list │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── main.c │ │ └── makefile ├── queue │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── red-black-tree │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c ├── stack │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── trie │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c └── vector │ ├── README.md │ ├── README.pt-br.md │ ├── c │ ├── Makefile │ └── main.c │ └── rust │ ├── Cargo.toml │ └── src │ └── main.rs ├── evolutionary-algorithms └── genetic-algorithm │ ├── README.md │ ├── README.pt-br.md │ └── c │ ├── Makefile │ └── main.c ├── graph ├── search │ ├── bfs │ │ ├── README.md │ │ ├── README.pt-br.md │ │ └── c │ │ │ ├── Makefile │ │ │ └── main.c │ ├── dfs │ │ ├── README.md │ │ ├── README.pt-br.md │ │ └── c │ │ │ ├── Makefile │ │ │ └── main.c │ └── dijkstra │ │ ├── README.md │ │ ├── README.pt-br.md │ │ └── c │ │ ├── Makefile │ │ └── main.c └── spanning-tree │ └── prim │ ├── README.md │ ├── README.pt-br.md │ └── c │ ├── Makefile │ └── main.c ├── machine-learning ├── fnn │ └── c │ │ ├── Makefile │ │ └── main.c ├── k-means │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c ├── knn │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c └── q-learning │ ├── README.md │ ├── README.pt-br.md │ └── c │ ├── Makefile │ └── main.c ├── math ├── euclidean-algorithm │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c ├── matrix │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c └── sieve-eratosthenes │ ├── README.md │ ├── README.pt-br.md │ └── c │ ├── Makefile │ └── main.c ├── searching ├── binary-search │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── exponential-search │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── interpolation-search │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs └── linear-search │ ├── README.md │ ├── README.pt-br.md │ ├── c │ ├── Makefile │ └── main.c │ └── rust │ ├── Cargo.toml │ └── src │ └── main.rs ├── sorting ├── bubble-sort │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── counting-sort │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── heapsort │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c ├── insertion-sort │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ ├── java │ │ ├── InsertionSort.java │ │ └── Makefile │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── merge-sort │ ├── README.md │ ├── README.pt-br.md │ └── c │ │ ├── Makefile │ │ └── main.c ├── quicksort │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ ├── java │ │ ├── Makefile │ │ └── QuicksortDuplicateKeys.java │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── selection-sort │ ├── README.md │ ├── README.pt-br.md │ ├── c │ │ ├── Makefile │ │ └── main.c │ └── rust │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs └── shell-sort │ ├── README.md │ ├── README.pt-br.md │ ├── c │ ├── Makefile │ └── main.c │ └── rust │ ├── Cargo.toml │ └── src │ └── main.rs └── string ├── lcs ├── README.md ├── README.pt-br.md └── c │ ├── Makefile │ └── main.c ├── levenshtein ├── README.md ├── README.pt-br.md └── c │ ├── Makefile │ └── main.c └── search ├── bmh ├── README.md ├── README.pt-br.md └── c │ ├── Makefile │ └── main.c ├── brute-force ├── README.md ├── README.pt-br.md └── c │ ├── Makefile │ └── main.c ├── kmp ├── README.md ├── README.pt-br.md └── c │ ├── Makefile │ └── main.c └── rabin-karp ├── README.md ├── README.pt-br.md └── c ├── Makefile └── main.c /.clang-format: -------------------------------------------------------------------------------- 1 | { 2 | BasedOnStyle: Microsoft, 3 | BreakBeforeBraces: Linux, 4 | BinPackArguments: false, 5 | ColumnLimit: 80, 6 | AllowAllParametersOfDeclarationOnNextLinux: true, 7 | AllowAllArgumentsOnNextLine: true, 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # IDEs 4 | .vscode/ 5 | 6 | # Build Artifacts 7 | *.elf 8 | *.lock 9 | target/ 10 | 11 | # Directories 12 | bin/ 13 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [workspace] 4 | members = [ 5 | "data-structures/disjoint-set/rust", 6 | "data-structures/queue/rust", 7 | "data-structures/stack/rust", 8 | "data-structures/vector/rust", 9 | "searching/binary-search/rust", 10 | "searching/interpolation-search/rust", 11 | "searching/exponential-search/rust", 12 | "searching/linear-search/rust", 13 | "sorting/bubble-sort/rust", 14 | "sorting/counting-sort/rust", 15 | "sorting/insertion-sort/rust", 16 | "sorting/selection-sort/rust", 17 | "sorting/shell-sort/rust", 18 | "sorting/quicksort/rust", 19 | ] 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Pedro Henrique Penna 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 | -------------------------------------------------------------------------------- /cryptography/caesar-cipher/README.md: -------------------------------------------------------------------------------- 1 | # Caesar Cipher 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /cryptography/caesar-cipher/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = caesar.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 3 "hello world" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/avl-tree/README.md: -------------------------------------------------------------------------------- 1 | # AVL Tree 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /data-structures/avl-tree/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = avl-tree.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 8 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/binary-heap/README.md: -------------------------------------------------------------------------------- 1 | # Binary Heap 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /data-structures/binary-heap/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = binary-heap.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/binary-heap/java/Makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | 4 | .SUFFIXES: .java .class 5 | 6 | # Define the source directory 7 | SRCDIR = . 8 | 9 | # Define the output directory for compiled classes 10 | BINDIR = . 11 | 12 | # List of Java files to be compiled 13 | CLASSES = MaxHeap.java MinHeap.java BinaryHeap.java MedianHeap.java 14 | 15 | default: classes 16 | 17 | classes: $(CLASSES:.java=.class) 18 | 19 | # Rule for compiling MaxHeap.java 20 | MaxHeap.class: $(SRCDIR)/MaxHeap.java 21 | $(JC) $(JFLAGS) -d $(BINDIR) $< 22 | 23 | # Rule for compiling MinHeap.java 24 | MinHeap.class: $(SRCDIR)/MinHeap.java 25 | $(JC) $(JFLAGS) -d $(BINDIR) $< 26 | 27 | # Rule for compiling BinaryHeap.java 28 | BinaryHeap.class: $(JFLAGS) -d $(BINDIR) $< 29 | 30 | # Rule for compiling MedianHeap.java 31 | MedianHeap.class: $(SRCDIR)/MedianHeap.java 32 | $(JC) $(JFLAGS) -d $(BINDIR) $< 33 | 34 | clean: 35 | $(RM) $(BINDIR)/*.class -------------------------------------------------------------------------------- /data-structures/binary-heap/java/MedianHeap.java: -------------------------------------------------------------------------------- 1 | import java.util.Comparator; 2 | 3 | /** 4 | * Dynamic median. Design a data type that supports insert in logarithmic time, find-the-median in constant time, and 5 | * remove-the-median in logarithmic time. If the number of keys in the data type is even, find/remove the lower median. 6 | **/ 7 | public class MedianHeap > { 8 | // The greater half of the elements are stored in a MinHeap. This grants easy access to the upper median. 9 | // The smaller half of the elements are stored in a MaxHeap. This grants easy access to the lower median. 10 | // The MaxHeap's size is <= the MinHeap's size -> both the median or the lower median are always in the MaxHeap. 11 | private final BinaryHeap minHeap; 12 | private final BinaryHeap maxHeap; 13 | 14 | public MedianHeap() { 15 | minHeap = new BinaryHeap(Comparator.reverseOrder()); 16 | maxHeap = new BinaryHeap(Comparator.naturalOrder()); 17 | } 18 | 19 | public void insert(E e) { 20 | if (maxHeap.isEmpty()) { 21 | maxHeap.insert(e); 22 | return; 23 | } 24 | 25 | if (minHeap.isEmpty()) { 26 | maxHeap.insert(e); 27 | minHeap.insert(maxHeap.deleteRoot()); 28 | return; 29 | } 30 | 31 | // If it's greater than the median, store it in the min heap. 32 | if (e.compareTo(findTheMedian()) > 0) 33 | minHeap.insert(e); 34 | // Since it's less than the median, store it in the max heap. 35 | else 36 | maxHeap.insert(e); 37 | 38 | // Maintain the invariants: 39 | // . Both heaps are balanced with each other; 40 | // . MaxHeap may have 1 more element. 41 | if (minHeap.size() > maxHeap.size()) 42 | maxHeap.insert(minHeap.deleteRoot()); 43 | else if (maxHeap.size() > minHeap.size() + 1) 44 | minHeap.insert(maxHeap.deleteRoot()); 45 | } 46 | 47 | public E findTheMedian() { 48 | return maxHeap.peek(); 49 | } 50 | 51 | public E removeTheMedian() { 52 | E median = maxHeap.deleteRoot(); 53 | 54 | // Maintain the invariant: MaxHeap's size >= MinHeap's size. 55 | if (maxHeap.size() < minHeap.size()) 56 | maxHeap.insert(minHeap.deleteRoot()); 57 | 58 | return median; 59 | } 60 | 61 | // Tests for correctness. 62 | public static void main(String[] args) { 63 | MedianHeap medianHeap = new MedianHeap<>(); 64 | 65 | // Populates the heap. 66 | for (int i = 0; i < 10; i++) 67 | medianHeap.insert(i); 68 | 69 | // Expected: 4 5 3 6 2 7 1 8 0 9. 70 | Integer[] expectedOutput = {4, 5, 3, 6, 2, 7, 1, 8, 0, 9}; 71 | 72 | for (int i = 0; i < 10; i++) 73 | assert medianHeap.removeTheMedian().equals(expectedOutput[i]); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /data-structures/binary-search-tree/README.md: -------------------------------------------------------------------------------- 1 | # Binary Search Tree 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /data-structures/binary-search-tree/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = binary-tree.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 8 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/binary-search-tree/java/Makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | 4 | .SUFFIXES: .java .class 5 | 6 | .java.class: 7 | $(JC) $(JFLAGS) $*.java 8 | 9 | CLASSES = BinaryTree.java 10 | 11 | default: classes 12 | 13 | classes: $(CLASSES:.java=.class) 14 | 15 | clean: 16 | $(RM) *.class -------------------------------------------------------------------------------- /data-structures/disjoint-set/README.md: -------------------------------------------------------------------------------- 1 | # Disjoint Set 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | ## What is a Disjoint Set? 8 | 9 | A Disjoint Set is a data structure that maintains a collection of elements, which are partitioned into multiple non-overlapping sets. This data structure enables elements to be grouped and partitioned into sets efficiently. 10 | 11 | ## What are the applications for a Disjoint Set? 12 | 13 | - In Kruskal's algorithm, a Disjoint Set may be used to keep track of the connected components of the graph, and to check whether or not adding an edge in an iteration of the algorithm would violate the properties of the minimal spawning tree under construction. 14 | - In image segmentation problems, a Disjoint Set may be used to keep track of the connections between the pixels of an image, as well as allowing pixels to be grouped into regions with similar properties. 15 | - In machine learning algorithms, a Disjoint Set may be used to group data into sets based on its characteristics and then aid in the training process. 16 | 17 | ## Who to implement a Disjoint Set? 18 | 19 | - **Using a collection of chained lists**, with linked each list representing a disjoint set. This implementation is easy to understand and only supports the `union` operation efficiently. 20 | - **Using a collection of trees**, with each tree representing a disjoint set. This implementation is more complex to understand, but supports 'join' and 'union' operations efficiently. 21 | 22 | ## What are the main operations of a Disjoint Set? 23 | 24 | - `union` merges two sets into a single one. 25 | - `find` identifies to which set a given element belongs. 26 | 27 | ### Union Operation 28 | 29 | 1. Find the set `X` to which element `x` belongs (`find` operation). 30 | 2. Find the set `Y` to which element `y` belongs (`find` operation). 31 | 3. Remove all elements from `Y` and place them into `X`. 32 | 33 | ### Find Operation 34 | 35 | 1. Pick up an arbitrary set `X` in the disjoint set. 36 | 2. Traverse all elements of `X` and check if any of them is the element being searched for. 37 | 3. If the searched element is found, return `X`. 38 | 4. If all elements of `X` were inspected, but none matches the element being searched, take another set `Y` which has not yet being considered, make `X = Y`, and repeat Steps 1 to 4. 39 | 5. If the searched element was not found, return `"element not found"`. 40 | -------------------------------------------------------------------------------- /data-structures/disjoint-set/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = dset.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 8 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/disjoint-set/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "disjoint-set" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | [dependencies] 9 | anyhow = "1.0.68" 10 | -------------------------------------------------------------------------------- /data-structures/list/README.md: -------------------------------------------------------------------------------- 1 | # Singly Linked List 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /data-structures/list/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Lista Singularmente Encadeada 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O Quê São Listas Singularmente Encadeadas?](#o-quê-são-listas-singularmente-encadeadas) 8 | - [Como Implementar Uma Lista Singularmente Encadeada?](#como-implementar-uma-lista-singularmente-encadeada) 9 | - [Quais São As Operações Básicas de Uma Lista Singularmente Encadeadas?](#quais-são-as-operações-básicas-de-uma-lista-singularmente-encadeadas) 10 | 11 | ## O Quê São Listas Singularmente Encadeadas? 12 | 13 | Uma lista singularmente encadeada, ou lista encadeada simples, é um tipo de [lista encadeada](/estruturas-de-dados/listas-encadeadas.html) onde suas células são encadeadas em apenas um sentido. Consequentemente, esse tipo de lista não suporta de forma eficiente a navegabilidade reversa, nem a inserção e remoção de elementos antecessores a um outro na lista. 14 | 15 | ## Como Implementar Uma Lista Singularmente Encadeada? 16 | 17 | - `l.celulas[]`: células que armazenam os elementos da lista singularmente encadeada. 18 | - `l.ultimo`: um ponteiro que referencia o último elemento da lista singularmente encadeada. 19 | - `l.comprimento`: um inteiro que conta o número de elementos na lista singularmente encadeada. 20 | 21 | ## Quais São As Operações Básicas de Uma Lista Singularmente Encadeadas? 22 | 23 | - [`inserir-sucessor()` insere um elemento como sucessor de outro em uma lista singularmente encadeada.](#operação-inserir-sucessor) 24 | - [`remover-sucessor()` remove o sucessor de um elemento em uma lista singularmente encadeada.](#operação-remover-sucessor) 25 | 26 | ### Operação Inserir Sucessor 27 | 28 | 1. Crie uma nova célula `q` na lista `l`. 29 | 2. Armazene o elemento `e` na célula `q`. 30 | 3. Encadeie o sucessor de `p` como o sucessor de `q`. 31 | 4. Encadeie `q` como o sucessor de `p`. 32 | 5. Incremente em uma unidade o contador de comprimento da lista `l.comprimento`. 33 | 6. Se `q` é a última célula da lista `l`, atualize `l.ultimo` para referenciar `q`. 34 | 35 | ### Operação Remover Sucessor 36 | 37 | 1. Verifique se a lista `l` está vazia. Em caso afirmativo, vá para o passo 2. Caso contrário, vá para o passo 3. 38 | 2. A lista está vazia, então retorne `"lista vazia"`. 39 | 3. Salve em `q` uma referência para o sucessor de `p`. 40 | 4. Salve em `e` o elemento armazenado em `q`. 41 | 5. Encadeie o sucessor de `q` como sucessor de `p`. 42 | 6. Decremente em uma unidade o contador de comprimento da lista `l.comprimento`. 43 | 7. Se `p` é a última célula da lista `l`, atualize `l.ultimo` para referenciar `p`. 44 | 8. Retorne o elemento `e`. 45 | -------------------------------------------------------------------------------- /data-structures/list/c/makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = linked-list.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 8 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/queue/README.md: -------------------------------------------------------------------------------- 1 | # Queue 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [What is a queue?](#what-is-a-queue) 8 | - [Where are queues used?](#where-are-queues-used) 9 | - [How to implement a queue?](#how-to-implement-a-queue) 10 | - [What are the basic operations of a queue?](#what-are-the-basic-operations-of-a-queue) 11 | 12 | ## What is a queue? 13 | 14 | A queue is a linear data structure in which elements are inserted at one end (the back of the queue) and removed from the other (the front of the queue). Due to this characteristic, queues are also known as FIFO (First-In First-Out) structures. 15 | 16 | An analogy for this data structure is a grocery store queue. People enter the line at the end and wait their turn, while people at the front of the line leave and are served. 17 | 18 | ## Where are queues used? 19 | 20 | - Process management in operating systems. Tasks are added to a queue to be executed and tasks are removed from the queue when they are completed. 21 | - Packet transmission in computer networks. Packets are added to a queue to be transmitted and are removed from the queue when they are delivered. 22 | - Search algorithms in artificial intelligence. States are added to the queue to be explored and are removed from the queue when they are processed. 23 | 24 | ## How to implement a queue? 25 | 26 | A queue `q` can be built with the following components: 27 | 28 | `q.cells[]`: cells that store the elements of the queue. 29 | `q.first`: a pointer that references the first element of the queue. 30 | `q.last`: a pointer that references the last element of the queue. 31 | `q.length`: an integer that counts the number of elements in the queue. 32 | 33 | ## What are the basic operations of a queue? 34 | 35 | - [`length()` returns the length of a queue.](#length-operation) 36 | - [`enqueue()` inserts an element at the end of a queue.](#enqueue-operation) 37 | - [`dequeue()` removes the element from the beginning of a queue.](#dequeue-operation) 38 | 39 | ### Length Operation 40 | 41 | 1. Return the value of `q.length`. 42 | 43 | ### Enqueue Operation 44 | 45 | 1. Update the last pointer of the queue `q.last` to reference a new cell. 46 | 2. Store the element `x` in the cell referenced by the last pointer of the queue `q.last. 47 | 3. Increment by one the length counter of the queue q.length. 48 | 49 | ### Dequeue Operation 50 | 51 | 1. Check if the queue `q` is empty. If affirmative, go to step 2. Otherwise, go to step 3. 52 | 2. The queue is empty, so return `"empty queue"`. 53 | 3. Save in `x` the element referenced by the first pointer of the queue `q.first`. 54 | 4. Update the first pointer of the queue `q.first` to reference the cell before the current first of the queue. 55 | 5. Decrement by one the length counter of the queue `q.length`. 56 | 6. Return the element `x`. 57 | -------------------------------------------------------------------------------- /data-structures/queue/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Fila 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é uma fila?](#o-quê-é-uma-fila) 8 | - [Onde filas são usadas?](#onde-filas-são-usadas) 9 | - [Qual é a estrutura de uma fila?](#qual-é-a-estrutura-de-uma-fila) 10 | - [Quais são as operações básicas de uma fila?](#quais-são-as-operações-básicas-de-uma-fila) 11 | 12 | ## O quê é uma fila? 13 | 14 | Uma fila é uma estrutura de dados linear em que elementos são inseridos em uma extremidade (final da fila) e retirados da outra (início da fila). Por essa característica, filas também são conhecidas como estruturas FIFO (_First-In First-Out_, Primeiro a Entrar Primeiro a Sair). 15 | 16 | Uma analogia para essa estrutura de dados são as filas de supermercado. Pessoas entram no final da fila e aguardam sua vez, enquanto pessoas do início da fila a deixam e são atendidas. 17 | 18 | ## Onde filas são usadas? 19 | 20 | - Gerenciamento de processos em sistemas operacionais. Tarefas são adicionadas a uma fila para serem executadas e as tarefas são removidas da fila quando são concluídas. 21 | - Transmissão de pacotes em redes de computadores. Pacotes são adicionados a uma fila para serem transmitidos e são removidos da fila quando são entregues. 22 | - Algoritmos de busca em inteligência artificial. Estados são adicionados à fila para serem explorados e são removidos da fila quando são processados. 23 | 24 | ## Qual é a estrutura de uma fila? 25 | 26 | Uma fila `f` pode ser construída com os seguintes componentes: 27 | 28 | - `f.celulas[]`: células que armazenam os elementos da fila. 29 | - `f.primeiro`: um ponteiro que referencia o primeiro elemento da fila. 30 | - `f.ultimo`: um ponteiro que referencia o último elemento da fila. 31 | - `f.comprimento`: um inteiro que conta o número de elementos na fila. 32 | 33 | ## Quais são as operações básicas de uma fila? 34 | 35 | - [`comprimento()` retorna o comprimento de uma fila.](#operação-comprimento) 36 | - [`enfileirar()` insere um elemento no final de uma fila.](#operação-enfileirar) 37 | - [`desenfileirar()` remove o elemento do início de uma fila.](#operação-desenfileirar) 38 | 39 | ### Operação Comprimento 40 | 41 | 1. Retorne o valor de `f.comprimento`. 42 | 43 | ### Operação Enfileirar 44 | 45 | 1. Atualize o ponteiro de último da fila `f.ultimo` para referenciar uma nova célula. 46 | 2. Armazene o elemento `x` na célula referenciada pelo ponteiro de último da fila `f.ultimo`. 47 | 3. Incremente em uma unidade o contador de comprimento da fila `f.comprimento`. 48 | 49 | ### Operação Desenfileirar 50 | 51 | 1. Verifique se a fila `f` está vazia. Em caso afirmativo, vá para o passo 2. Caso contrário, vá para o passo 3. 52 | 2. A fila está vazia, então retorne`"fila vazia"`. 53 | 3. Salve em `x` o elemento referenciado pelo ponteiro de primeiro da fila `f.primeiro`. 54 | 4. Atualize o ponteiro de topo da fila `f.primeiro` para referenciar a célula anterior à primeira atual da fila. 55 | 5. Decremente em uma unidade o contador de comprimento da fila `f.comprimento`. 56 | 6. Retorne o elemento `x`. 57 | -------------------------------------------------------------------------------- /data-structures/queue/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = queue.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/queue/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "queue" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | anyhow = "1.0.68" 12 | -------------------------------------------------------------------------------- /data-structures/red-black-tree/README.md: -------------------------------------------------------------------------------- 1 | # Red-Black Tree 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /data-structures/red-black-tree/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = rb-tree.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 8 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/stack/README.md: -------------------------------------------------------------------------------- 1 | # Stack 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [What is a stack?](#what-is-a-stack) 8 | - [Where are stacks used?](#where-are-stacks-used) 9 | - [How to implement a stack?](#how-to-implement-a-stack) 10 | - [What are the basic operations in stacks?](#what-are-the-basic-operations-in-stacks) 11 | 12 | ## What is a stack? 13 | 14 | A stack is a linear data structure in which elements are added and removed from the same end. Because of this characteristic, stacks are also known as LIFO (Last-In First-Out) structures. 15 | 16 | An analogy for this data structure is a stack of books. Books are always placed and removed from the top of the stack. 17 | 18 | ## Where are stacks used? 19 | 20 | - Undo and Redo -- Stacks are used in text editors to store user actions, allowing for undoing and redoing actions. 21 | - Navigation History -- Stacks are used to store the pages visited by the user in a web browser, allowing the user to go back to the previous page when the "back" button is pressed. 22 | - Search Algorithms -- Stacks are used in search algorithms to store pending states to be explored. 23 | - Execution Stacks -- When a function is called, the parameters and the return address are pushed onto the stack. When the function returns, the return address is popped and control is transferred back to the previous call. 24 | 25 | ## How to implement a stack? 26 | 27 | A stack `s` can be constructed with the following components: 28 | 29 | - `s.cells[]`: cells that store the elements of the stack. 30 | - `s.top`: a pointer that references the top element of the stack. 31 | - `s.size`: an integer that counts the number of elements in the stack. 32 | 33 | ## What are the basic operations in stacks? 34 | 35 | - [`size()` returns the number of elements in a stack.](#size-operation) 36 | - [`push()` inserts an element on top of a stack.](#push-operation) 37 | - [`pop()` removes the top element of a stack.](#pop-operation) 38 | 39 | ### Size Operation 40 | 41 | 1. Return the value of `p.size`. 42 | 43 | ### Push Operation 44 | 45 | 1. Update the top pointer of stack `s.top` to reference a new cell. 46 | 2. Store the element `x` in the cell referenced by the top pointer of stack `s.top`. 47 | 3. Increment the size counter of stack `s.size` by one. 48 | 49 | ### Pop Operation 50 | 51 | 1. Check if stack `s` is empty. If yes, go to Step 2. Otherwise, go to Step 3. 52 | 2. The stack is empty, so return `"empty stack"`. 53 | 3. Save in x the element referenced by the top pointer of stack `s.top`. 54 | 4. Update the top pointer of stack `s.top` to reference the cell below the current top. 55 | 5. Decrement the size counter of stack `s.size` by one. 56 | 6. Return element `x`. 57 | -------------------------------------------------------------------------------- /data-structures/stack/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Pilha 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é uma pilha?](#o-quê-é-uma-pilha) 8 | - [Onde pilhas são usadas?](#onde-pilhas-são-usadas) 9 | - [Qual é a estrutura de uma pilha?](#qual-é-a-estrutura-de-uma-pilha) 10 | - [Quais são as operações básicas de uma pilha?](#quais-são-as-operações-básicas-de-uma-pilha) 11 | 12 | ## O quê é uma pilha? 13 | 14 | Uma pilha é uma estrutura de dados linear em que elementos são adicionados e retirados de uma mesma extremidade. Por essa característica, pilhas também são conhecidas como estruturas LIFO (_Last-In First-Out_, Último a Entrar Primeiro a Sair). 15 | 16 | Uma analogia para essa estrutura de dados é uma pilha de livros. Livros são sempre colocados e retirados do topo da pilha. 17 | 18 | ## Onde pilhas são usadas? 19 | 20 | - Desfazer e Refazer -- Pilhas são usadas em editores de texto para armazenar as ações do usuário, permitindo desfazer e refazer ações. 21 | - Navegação de Histórico -- Pilhas são usadas para armazenar as páginas visitadas pelo usuário em um navegador web, permitindo que o usuário volte para a página anterior ao pressionar o botão "voltar". 22 | - Algoritmos de Busca -- Pilhas são usadas em algoritmos de busca para armazenar os estados pendentes de serem explorados. 23 | - Pilhas de Execução -- Quando uma função é chamada, os parâmetros e o endereço de retorno são empilhados na pilha. Quando a função retorna, o endereço de retorno é desempilhado e o controle é transferido de volta para a chamada anterior. 24 | 25 | ## Qual é a estrutura de uma pilha? 26 | 27 | Uma pilha `p` pode ser construída com os seguintes componentes: 28 | 29 | - `p.celulas[]`: células que armazenam os elementos da pilha. 30 | - `p.topo`: um ponteiro que referencia o elemento do topo da pilha. 31 | - `p.tamanho`: um inteiro que conta o número de elementos na pilha. 32 | 33 | ## Quais são as operações básicas de uma pilha? 34 | 35 | - [`tamanho()` retorna o número de elementos em uma pilha.](#operação-tamanho) 36 | - [`empilhar()` insere um elemento no topo de uma pilha.](#operação-empilhar) 37 | - [`desempilhar()` remove o elemento do topo de uma pilha.](#operação-desempilhar) 38 | 39 | ### Operação Tamanho 40 | 41 | 1. Retorne o valor de `p.tamanho`. 42 | 43 | ### Operação Empilhar 44 | 45 | 1. Atualize o ponteiro de topo da pilha `p.topo` para referenciar uma nova célula. 46 | 2. Armazene o elemento `x` na célula referenciada pelo ponteiro de topo da pilha `p.topo`. 47 | 3. Incremente em uma unidade o contador de tamanho da pilha `p.tamanho`. 48 | 49 | ### Operação Desempilhar 50 | 51 | 1. Verifique se a pilha `p` está vazia. Em caso afirmativo, vá para o Passo 2. Caso contrário, vá para o Passo 3. 52 | 2. A pilha está vazia, então retorne `"pilha vazia"`. 53 | 3. Salve em `x` o elemento referenciado pelo ponteiro de topo da pilha `p.topo`. 54 | 4. Atualize o ponteiro de topo da pilha `p.topo` para referenciar a célula abaixo do topo atual. 55 | 5. Decremente em uma unidade o contador de tamanho da pilha `p.tamanho`. 56 | 6. Retorne o elemento `x`. 57 | -------------------------------------------------------------------------------- /data-structures/stack/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = stack.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/stack/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "stack" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | anyhow = "1.0.68" 12 | -------------------------------------------------------------------------------- /data-structures/trie/README.md: -------------------------------------------------------------------------------- 1 | # Trie 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /data-structures/trie/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = queue.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose a abra ca da bra abra cadabra abracadabra 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/vector/README.md: -------------------------------------------------------------------------------- 1 | # Vector 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [What is a vector?](#what-is-a-vector) 8 | - [Where are vectores used?](#where-are-vectores-used) 9 | - [How to implement a vector?](#how-to-implement-a-vector) 10 | - [What are the basic operations in a vector?](#what-are-the-basic-operations-in-a-vector) 11 | 12 | ## What is a vector? 13 | 14 | A vector is a linear data structure that efficiently supports random access to any of its elements. To do this, the elements of a vector must all have the same type and be stored contiguously in memory. Thus, an element can be uniquely indexed from its relative position in this data structure. 15 | 16 | An analogy for vectors are staircases. Several steps of the same size are arranged contiguously and a step can be uniquely identified by its relative position to the first step of the staircase. 17 | 18 | ## Where are vectores used? 19 | 20 | - To implement other data structures, such as Stacks and Queues. 21 | 22 | ## How to implement a vector? 23 | 24 | A vector `v` can be constructed with the following components: 25 | 26 | - `v.elements[]`: an array that stores the elements of the vector. 27 | - `v.length`: an integer that indicates the number of elements stored in the vector. 28 | - `v.capacity`: an integer that indicates the maximum number of elements that can be stored in the vector. 29 | 30 | ## What are the basic operations in a vector? 31 | 32 | - [`insert()` inserts an element in a vector.](#insert-operation) 33 | - [`remove()` removes an element from a vector.](#remove-operation) 34 | 35 | ### Insert Operation 36 | 37 | 1. If the length of the vector `v.length` is equal to its capacity `v.capacity`, expand the capacity of the vector. 38 | 2. Increment the length of the vector `v.length` by one. 39 | 3. Shift all elements of the vector `v` that are to the right of the insertion index `i` one position to the right. 40 | 4. Store the element `x` at position `i` of the vector `v`. 41 | 42 | ### Remove Operation 43 | 44 | 1. If the removal index `i` is greater than the length of the vector `v.length`, return `"invalid index"`. 45 | 2. Save in `x` the element stored at position `i` of the vector `v`. 46 | 3. Shift all elements of the vector `v` that are to the right of the removal index `i` one position to the left. 47 | 4. Decrement the length of the vector `v.length` by one. 48 | 5. Return the element `x`. 49 | -------------------------------------------------------------------------------- /data-structures/vector/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Vetor 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é um vetor?](#o-quê-é-um-vetor) 8 | - [Onde vetores são usados?](#onde-vetores-são-usados) 9 | - [Qual é a estrutura de um vetor?](#qual-é-a-estrutura-de-um-vetor) 10 | - [Quais são as operações básicas de um vetor?](#quais-são-as-operações-básicas-de-um-vetor) 11 | 12 | ## O quê é um vetor? 13 | 14 | Um vetor é uma estrutura de dados linear que suporta de forma eficiente o acesso aleatório a qualquer um de seus elementos. Para isso, os elementos de um vetor devem todos possuir o mesmo tipo e serem armazenados de forma contígua em memória. Assim, um elemento pode ser unicamente indexado a partir de sua posição relativa nessa estrutura de dados. 15 | 16 | Uma analogia para vetores são as escadas. Vários degraus de mesmo tamanho são dispostos contiguamente e um degrau pode ser unicamente identificado pela sua posição relativa ao primeiro degrau da escada. 17 | 18 | ## Onde vetores são usados? 19 | 20 | - Na implementação de outras estruturas de dados como Pilhas e Filas. 21 | 22 | ## Qual é a estrutura de um vetor? 23 | 24 | Um vetor `v` pode ser construído com os seguintes componentes: 25 | 26 | - `v.elementos[]`: um arranjo que armazena os elementos do vetor. 27 | - `v.comprimento`: um inteiro que indica o número de elementos armazenados no vetor. 28 | - `v.capacidade`: um inteiro que indica o número máximo de elementos que podem ser armazenados no vetor. 29 | 30 | ## Quais são as operações básicas de um vetor? 31 | 32 | - [`inserir()` insere um elemento em um vetor.](#operação-inserir) 33 | - [`remover()` remove um elemento de um vetor.](#operação-remover) 34 | 35 | ### Operação Inserir 36 | 37 | 1. Se o comprimento do vetor `v.comprimento` é igual a sua capacidade `v.capacidade`, expanda a capacidade do vetor. 38 | 2. Incremente em uma unidade o comprimento do vetor `v.comprimento`. 39 | 3. Desloque em uma posição para a direita, todos os elementos do vetor `v` que estão à direita do índice de inserção `i`. 40 | 4. Armazene o elemento `x` na posição `i` do vetor `v`. 41 | 42 | ### Operação Remover 43 | 44 | 1. Se o índice de remoção `i` é maior que o comprimento do vetor `v.comprimento`, retorne `"índice inválido"`. 45 | 2. Salve em `x` o elemento armazenado na posição `i` do vetor `v`. 46 | 3. Desloque em uma posição para a esquerda, todos os elementos do vetor `v` que estão à direita do índice de remoção `i`. 47 | 4. Decremente em uma unidade o comprimento do vetor `v.comprimento`. 48 | 5. Retorne o elemento `x`. 49 | -------------------------------------------------------------------------------- /data-structures/vector/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = vector.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /data-structures/vector/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "vector" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | anyhow = "1.0.68" 12 | -------------------------------------------------------------------------------- /evolutionary-algorithms/genetic-algorithm/README.md: -------------------------------------------------------------------------------- 1 | # K-Means Clustering 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /evolutionary-algorithms/genetic-algorithm/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = ga.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 64 100 0.80 0.50 0.05 0.02 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | $(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /graph/search/bfs/README.md: -------------------------------------------------------------------------------- 1 | # Breadth-First Search 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /graph/search/bfs/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Busca em Largura 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é a Busca em Largura?](#o-quê-é-a-busca-em-largura) 8 | - [Quais são as características da Busca em Largura?](#quais-são-as-características-da-busca-em-largura) 9 | - [Quais as aplicações da Busca em Largura?](#quais-as-aplicações-da-busca-em-largura) 10 | - [Qual é o algoritmo de Busca em Largura?](#qual-é-o-algoritmo-de-busca-em-largura) 11 | - [Qual o desempenho da Busca em Largura?](#qual-o-desempenho-da-busca-em-largura) 12 | 13 | ## O quê é a Busca em Largura? 14 | 15 | A Busca em Largura (BFS -- _Breadth-First Search_) é um algoritmo de busca em grafos. Esse algoritmo funciona explorando o grafo em níveis, a partir de um nó inicial, usando uma fila do tipo primeiro a entrar, primeiro a sair. 16 | 17 | ## Quais são as características da Busca em Largura? 18 | 19 | - A Busca em Largura possibilita encontrar a menor distância, em número de arestas, entre dois nós de um grafo. 20 | - A Busca em Largura é um algoritmo de busca não informada, uma vez que não usa nenhuma informação para direcionar a busca. 21 | - Busca em Largura é ineficiente em grafos grandes ou profundos. 22 | 23 | ## Quais as aplicações da Busca em Largura? 24 | 25 | - **Encontrar a menor Rota em Um Grafo** -- A Busca em Largura pode ser usada para encontrar a rota mais curta entre dois nós de um grafo. 26 | 27 | - **Verificar Conexão em Grafos**: A Busca em Largura pode ser usada para verificar se dois nós estão conectados em um grafo e, se estiverem, encontrar o caminho de conexão. 28 | 29 | - **Encontrar Componentes Conectados em Um Grafo** -- A Busca em Largura pode ser usada para encontrar todas os componentes conectados em um grafo não direcionado. 30 | 31 | - **Resolução de Problemas** -- A Busca em Largura pode ser usada como uma técnica de busca para resolver problemas, como encontrar a solução para um quebra-cabeça ou encontrar o objetivo em um jogo. 32 | 33 | ## Qual é o algoritmo de Busca em Largura? 34 | 35 | 1. Inicialize uma fila com o nó inicial e marque-o como visitado. 36 | 2. Enquanto a fila não estiver vazia: 37 | 1. Remova o nó da frente da fila e verifique se ele é o objetivo. 38 | 2. Em caso afirmativo, retorne o caminho até ele. 39 | 3. Caso contrário, adicione todos os seus nós não visitados adjacentes na fila e marque-os como visitados. 40 | 3. Se a fila estiver vazia e o objetivo não tiver sido encontrado, retorne `"sem solução"`. 41 | 42 | ## Qual o desempenho da Busca em Largura? 43 | 44 | A Busca em Largura possui uma complexidade linear de tempo e espaço, em função do número de nós `|V|` e arestas `|E|` do grafo: 45 | 46 | - Complexidade de Tempo: `O(|V| + |E|)` 47 | - Complexidade de Espaço: `O(|V|)` 48 | 49 | Alternativamente, quando o grafo de busca é muito grande, a complexidade de tempo e espaço da Busca em Largura é escrita em função do número do fator de ramificação do grafo `b` (_branch factor_) e a distância `d` do nó inicial ao nó objetivo, e possui uma complexidade exponencial: 50 | 51 | - Complexidade de Tempo: `O(bᵈ)` 52 | - Complexidade de Espaço: `O(bᵈ)` 53 | -------------------------------------------------------------------------------- /graph/search/bfs/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = bfs.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "8" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /graph/search/dfs/README.md: -------------------------------------------------------------------------------- 1 | # Depth-First Search 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /graph/search/dfs/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Busca em Profundidade 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é a Busca em Profundidade?](#o-quê-é-a-busca-em-profundidade) 8 | - [Quais são as características da Busca em Profundidade?](#quais-são-as-características-da-busca-em-profundidade) 9 | - [Quais as aplicações da Busca em Profundidade?](#quais-as-aplicações-da-busca-em-profundidade) 10 | - [Qual é o algoritmo de Busca em Profundidade?](#qual-é-o-algoritmo-de-busca-em-profundidade) 11 | - [Qual o desempenho da Busca em Profundidade?](#qual-o-desempenho-da-busca-em-profundidade) 12 | 13 | ## O quê é a Busca em Profundidade? 14 | 15 | A Busca em Profundidade (DFS -- _Depth-First Search_) é um algoritmo de busca em grafos. Esse algoritmo explora um grafo a partir de um nó inicial, usando uma pilha para processar os nós não visitados. 16 | 17 | ## Quais são as características da Busca em Profundidade? 18 | 19 | - A Busca em Profundidade é um algoritmo de busca não informada, uma vez que não usa nenhuma informação para direcionar a busca. 20 | - A Busca em Profundidade não garante que a solução encontrada seja a melhor possível. 21 | - A Busca em Profundidade utiliza uma pilha para rastrear o nós que precisam ser visitados. 22 | - A Busca em Profundidade pode ser mais eficiente em termos de espaço de memória do que outros algoritmos de busca, como a Busca em Largura. 23 | 24 | ## Quais as aplicações da Busca em Profundidade? 25 | 26 | - **Realizar a Ordenação Topológica de Grafos** -- A Busca em Profundidade pode ser usada para realizar a ordenação topológica de um grafo direcionado e acíclico, isto é listar os nós do grafo de forma que suas dependências sejam respeitadas. 27 | 28 | - **Verificar Conexão em Grafos** -- A Busca em Profundidade pode ser usada para verificar se dois nós de um grafo estão conectados e, caso estejam, encontrar o caminho que os conecta. 29 | 30 | - **Encontrar Componentes Conectados em Grafos** -- A Busca em Profundidade pode ser usada para encontrar todas os componentes conectados em um grafo não direcionado. 31 | 32 | - **Detectar Ciclos em Grafos** -- A Busca em Profundidade pode ser usada detectar ciclos em um grafo direcionado. 33 | 34 | ## Qual é o algoritmo de Busca em Profundidade? 35 | 36 | 1. Inicialize uma pilha com o nó inicial e marque-o como visitado. 37 | 2. Enquanto a pilha não estiver vazia: 38 | 1. Remova o nó do topo da pilha e verifique se ele é o objetivo. 39 | 2. Em caso afirmativo, retorne o caminho até ele. 40 | 3. Caso contrário, adicione todos os nós não visitados adjacentes na pilha e marque-os como visitados. 41 | 3. Se a pilha estiver vazia e o objetivo não tiver sido encontrado, retorne `"sem solução"`. 42 | 43 | ## Qual o desempenho da Busca em Profundidade? 44 | 45 | A Busca em Profundidade possui uma complexidade linear de tempo e espaço, em função do número de nós `|V|` e arestas `E` do grafo: 46 | 47 | - Complexidade de Tempo: `O(|V| + |E|)` 48 | - Complexidade de Espaço: `O(|V|)` 49 | 50 | Alternativamente, quando o grafo de busca é muito grande, a complexidade de tempo e espaço da BUsca em Profundidade é escrita em função do número do fator de ramificação do grafo `b` (_branch factor_) e a distância `d` do nó inicial ao nó objetivo, e possui uma complexidade exponencial: 51 | 52 | - Complexidade de Tempo: `O(bᵈ)` 53 | - Complexidade de Espaço: `O(bd)` 54 | -------------------------------------------------------------------------------- /graph/search/dfs/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = dfs.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "8" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /graph/search/dijkstra/README.md: -------------------------------------------------------------------------------- 1 | # Dijkstra's Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /graph/search/dijkstra/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = dijkstra.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "8" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /graph/spanning-tree/prim/README.md: -------------------------------------------------------------------------------- 1 | # Prim's Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /graph/spanning-tree/prim/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Algoritmo de 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o Algoritmo de Prim?](#o-quê-é-o-algoritmo-de-prim) 8 | - [Quais são as características do Algoritmo de Prim?](#quais-são-as-características-do-algoritmo-de-prim) 9 | - [Quais as aplicações do Algoritmo de Prim?](#quais-as-aplicações-do-algoritmo-de-prim) 10 | - [Qual é o Algoritmo de Prim?](#qual-é-o-algoritmo-de-prim) 11 | - [Qual o desempenho do Algoritmo de Prim?](#qual-o-desempenho-do-algoritmo-de-prim) 12 | 13 | ## O quê é o Algoritmo de Prim? 14 | 15 | O Algoritmo de Prim é um algoritmo para encontrar a árvore geradora mínima em um grafo não direcionado e ponderado -- uma sub-árvore conectada do grafo original que inclui todos os vértices e tem o menor peso possível. O algoritmo funciona adicionando vértices à árvore geradora mínima um a um, até que todos os possível vértices tenham sido incluídos na sub-árvore. Em cada iteração, o algoritmo adiciona o vértice com menor peso de aresta que está conectado a um vértice na sub-árvore. 16 | 17 | O Algoritmo de Prim foi criado inicialmente por Vojtěch Jarník em 1930 e posteriormente republicado por Robert Prim em 1957 e Edsger Dijkstra em 1959. Por esse motivo, o algoritmo também é conhecido como Algoritmo de Jarník, Algoritmo de Prim-Jarník, Algoritmo de Prim-Dijkstra ou então Algoritmo DJP. 18 | 19 | ## Quais são as características do Algoritmo de Prim? 20 | 21 | - O Algoritmo de Prim é um algoritmo guloso. 22 | - O Algoritmo de Prim usa uma Heap como estrutura auxiliar. 23 | 24 | ## Quais as aplicações do Algoritmo de Prim? 25 | 26 | - **Sistemas de Roteamento em Redes de Computadores** -- o Algoritmo de Prim pode ser usado para encontrar o caminho mais curto entre dois nós de uma rede de computadores. 27 | - **Análise de Dados de Distância Genética** -- O Algoritmo de Prim pode ser usado para construir uma árvore filogenética que representa a relação evolutiva entre diferentes espécies ou populações com base em sua distância genética. 28 | - **Redes de distribuição de energia elétrica** -- O Algoritmo de Prim pode ser usado para encontrar a rede de distribuição de energia elétrica mais eficiente em termos de custo e perda de energia. 29 | 30 | ## Qual é o Algoritmo de Prim? 31 | 32 | 1. Selecione um vértice inicial, adicione-o na árvore geradora mínima e marque-o como visitado. 33 | 2. Encontre a aresta de menor peso que conecta um dos vértices da árvore geradora mínima com um vértice ainda não visitado. 34 | 3. Inclua a aresta encontrada na árvore geradora mínima e marque o vértice conectado pela aresta como visitado. 35 | 4. Repita os Passos 2 e 3 até que todos os vértices do grafo estejam na árvore geradora mínima. 36 | 37 | ## Qual o desempenho do Algoritmo de Prim? 38 | 39 | O desempenho do algoritmo de Prim depende do número de vértices `|V|` e arestas `|E|` do grafo. Em uma implementação usando uma Heap Binária, o Algoritmo de Prim possui uma complexidade de tempo super linear: 40 | 41 | - `O((|V| + |E|) * log |V|)` comparações 42 | -------------------------------------------------------------------------------- /graph/spanning-tree/prim/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = prim.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "8" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /machine-learning/fnn/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = fnn.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 100000 0.1 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ -lm 52 | -------------------------------------------------------------------------------- /machine-learning/k-means/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Clusterização K-Means 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o _K-Means_?](#o-quê-é-o-k-means) 8 | - [Quais são as características do _K-Means_?](#quais-são-as-características-do-k-means) 9 | - [Quais as aplicações do _K-Means_?](#quais-as-aplicações-do-k-means) 10 | - [Qual é o algoritmo _K-Means_?](#qual-é-o-algoritmo-k-means) 11 | - [Qual o desempenho do _K-Means_?](#qual-o-desempenho-do-k-means) 12 | 13 | ## O quê é o _K-Means_? 14 | 15 | O K-means é um algoritmo de aprendizado de máquina não-supervisionado proposto por Hugo Steinhaus em 1956 que agrupa dados similares em clusters. Ele funciona de forma iterativa, escolhendo `k` centroides, atribuindo cada ponto de dados ao centroide mais próximo e recalculando os centroides até que não haja mais mudanças ou um número máximo de iterações seja atingido. 16 | 17 | ## Quais são as características do _K-Means_? 18 | 19 | - O _K-Means_ é um algoritmo de aprendizado de máquina. 20 | - O _K-Means_ é um algoritmo de agrupamento. 21 | - O _K-Means_ é um algoritmo não-supervisionado. 22 | - O _K-Means_ é um algoritmo iterativo. 23 | - O _K-Means_ converge para uma solução local ótima. 24 | - O _K-Means_ possui desempenho sensível à inicialização e às características dos dados. 25 | 26 | ## Quais as aplicações do _K-Means_? 27 | 28 | - **Segmentação de Clientes** -- O _K-Means_ pode ser usado para agrupar clientes com base em suas características, permitindo que as empresas personalizem suas campanhas de marketing para cada grupo. 29 | 30 | - **Agrupamento de Notícias** -- O _K-Means_ pode ser usado para agrupar notícias em categorias com base no seu conteúdo, tornando mais fácil para os usuários encontrar notícias relevantes. 31 | 32 | - **Detecção de Fraudes** -- O _K-Means_ pode ser usado para detectar transações suspeitas agrupando transações semelhantes e identificando aquelas que são diferentes do grupo. 33 | 34 | - **Análise de Imagens** -- O _K-Means_ pode ser usado para segmentar imagens em regiões com características semelhantes, facilitando a análise de padrões em imagens. 35 | 36 | - **Bioinformática**: O _K-Means_ pode ser usado para agrupar proteínas ou genes com base em suas características, permitindo que os cientistas identifiquem novas descobertas na área da biologia molecular. 37 | 38 | ## Qual é o algoritmo _K-Means_? 39 | 40 | 1. Escolha um valor `k` para o número de clusters desejados. 41 | 2. Inicialize aleatoriamente os centroides dos `k` clusters. 42 | 3. Atribua cada ponto de dados ao centroide mais próximo com base na distância euclidiana entre o ponto de dados e os centroides. 43 | 4. Recalcule os centroides de cada cluster como a média dos pontos de dados atribuídos a ele. 44 | 5. Repita os Passos 3 e 4 até que não haja mais mudanças ou um número máximo de iterações seja atingido. 45 | 6. O resultado final é um conjunto de `k` clusters, onde cada ponto de dados pertence a um cluster específico. 46 | 47 | ## Qual o desempenho do _K-Means_? 48 | 49 | O desempenho do algoritmo _K-Means_ é afetado por diversos fatores, como a escolha do número de clusters `k`, as características do conjunto de dados, a escolha inicial dos centroides e o número de iterações. Em geral, a complexidade do algoritmo é polinomial, em função do número de pontos `n`, dimensão `d` dos dados, do número de clusters `k` e o número de iterações `i`: 50 | 51 | - `O(ndki)` operações de ponto flutuante. 52 | -------------------------------------------------------------------------------- /machine-learning/k-means/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = kmeans.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024 16 4" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /machine-learning/knn/README.md: -------------------------------------------------------------------------------- 1 | # K-Nearest Neighbors 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /machine-learning/knn/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = knn.elf 11 | 12 | # Default Run Arguments 13 | export ARGS ?= --verbose 8 3 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | $(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /machine-learning/q-learning/README.md: -------------------------------------------------------------------------------- 1 | # Q-Learning 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /machine-learning/q-learning/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = q-learning.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /math/euclidean-algorithm/README.md: -------------------------------------------------------------------------------- 1 | # Euclidean Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /math/euclidean-algorithm/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Algoritmo de Euclides 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o _Algoritmo de Euclides_?](#o-quê-é-o-algoritmo-de-euclides) 8 | - [Quais são as aplicações do _Algoritmo de Euclides_?](#quais-são-as-aplicações-do-algoritmo-de-euclides) 9 | - [Quais são os passos do _Algoritmo de Euclides_?](#quais-são-os-passos-do-algoritmo-de-euclides) 10 | - [Qual a complexidade do _Algoritmo de Euclides_?](#qual-a-complexidade-do-algoritmo-de-euclides) 11 | 12 | ## O quê é o _Algoritmo de Euclides_? 13 | 14 | O _Algoritmo de Euclides_ é um método para encontrar o maior divisor comum (MDC) entre dois números inteiros. Esse método foi descritor pelo matemático grego Euclides em seu livro "Elementos". 15 | 16 | O _Algoritmo de Euclides_ é baseado na observação de que, se o resto da divisão de um número `a` por um número `b` é `r`, então o MDC entre `a` e `b` é o mesmo que o MDC entre `b` e `r`. 17 | 18 | ## Quais são as aplicações do _Algoritmo de Euclides_? 19 | 20 | - **Simplificação de Frações** - O algoritmo de Euclides é frequentemente usado para simplificar frações. O MDC entre o numerador e o denominador de uma fração pode ser calculado usando o algoritmo de Euclides, e em seguida a fração pode ser simplificada dividindo ambos os termos pelo MDC. 21 | - **Cálculo de Congruências Lineares** - O algoritmo de Euclides é usado para resolver equações de congruência linear, que são importantes na teoria dos números e na criptografia. 22 | - **Criptografia** - O algoritmo de Euclides é usado em criptografia de chave pública para calcular chaves de criptografia e assinaturas digitais. 23 | 24 | ## Quais são os passos do _Algoritmo de Euclides_? 25 | 26 | 1. Denote como `a` e `b` dois números inteiros. 27 | 2. Se `b` for igual a `0` retorno `a`. 28 | 3. Caso contrário, calcule o resto da divisão de `a` por `b`. 29 | 4. Substitua `a` por `b` e `b` por `r`. 30 | 5. Retorne ao Passo 1. 31 | 32 | ## Qual a complexidade do _Algoritmo de Euclides_? 33 | 34 | A complexidade do algoritmo de Euclides depende do tamanho dos números de entrada. Para dois números inteiros `a` e `b`, a complexidade do Algoritmo de Euclides é `O(log(min(a, b)))`, onde `log` representa o logaritmo na base 2 e `min(a, b)` é o menor dos dois números `a` e `b`. 35 | -------------------------------------------------------------------------------- /math/euclidean-algorithm/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = euclidean.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 108 92 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /math/euclidean-algorithm/c/main.c: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Pedro Henrique Penna 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //============================================================================== 12 | // Euclidean Algorithm 13 | //============================================================================== 14 | 15 | // Computes the greatest common divisor of two numbers. 16 | static unsigned euclidean_algorithm(unsigned a, unsigned b) 17 | { 18 | unsigned r = 0; 19 | 20 | while (b != 0) { 21 | r = a % b; 22 | a = b; 23 | b = r; 24 | } 25 | 26 | return (a); 27 | } 28 | 29 | //============================================================================== 30 | // Test 31 | //============================================================================== 32 | 33 | // Tests function. 34 | static void test(unsigned a, unsigned b, bool verbose) 35 | { 36 | double tstart = 0.0; 37 | double tend = 0.0; 38 | unsigned gcd = 0; 39 | const double MICROSECS = ((CLOCKS_PER_SEC / 1000000.0)); 40 | 41 | if (verbose) { 42 | printf("a = %u, b = %u\n", a, b); 43 | } 44 | 45 | // Run. 46 | tstart = clock(); 47 | gcd = euclidean_algorithm(a, b); 48 | tend = clock(); 49 | if (verbose) { 50 | printf("gcd = %u\n", gcd); 51 | } 52 | printf("%12s: %2.lf us\n", 53 | "euclidean_algorithm()", 54 | (tend - tstart) / MICROSECS); 55 | } 56 | 57 | //============================================================================== 58 | // Usage 59 | //============================================================================== 60 | 61 | // Prints program usage and exits. 62 | static void usage(char *const argv[]) 63 | { 64 | printf("%s - Testing program for eucliean algorithm.\n", argv[0]); 65 | printf("Usage: %s [--verbose] \n", argv[0]); 66 | exit(EXIT_FAILURE); 67 | } 68 | 69 | //============================================================================== 70 | // Main 71 | //============================================================================== 72 | 73 | // Drives the test function. 74 | int main(int argc, char *const argv[]) 75 | { 76 | unsigned a = 0; 77 | unsigned b = 0; 78 | bool verbose = false; 79 | 80 | // Check for missing arguments. 81 | if ((argc < 3) || (argc > 4)) { 82 | printf("Error: invalid number of arguments.\n"); 83 | usage(argv); 84 | } 85 | 86 | // Parse command line arguments. 87 | if (argc == 3) { 88 | sscanf(argv[1], "%u", &a); 89 | sscanf(argv[2], "%u", &b); 90 | } else if ((argc == 4) && (!strcmp(argv[1], "--verbose"))) { 91 | sscanf(argv[2], "%u", &a); 92 | sscanf(argv[3], "%u", &b); 93 | verbose = true; 94 | } else { 95 | printf("Error: invalid arguments.\n"); 96 | usage(argv); 97 | } 98 | 99 | // Run it! 100 | test(a, b, verbose); 101 | 102 | return (EXIT_SUCCESS); 103 | } 104 | -------------------------------------------------------------------------------- /math/matrix/README.md: -------------------------------------------------------------------------------- 1 | # Matrices 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /math/matrix/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = matrix.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 4 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /math/sieve-eratosthenes/README.md: -------------------------------------------------------------------------------- 1 | # Sieve of Eratosthenes 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /math/sieve-eratosthenes/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Crivo de Eratóstenes 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o _Crivo de Eratóstenes_?](#o-quê-é-o-crivo-de-eratóstenes) 8 | - [Quais são as características do _Crivo de Eratóstenes_?](#quais-são-as-características-do-crivo-de-eratóstenes) 9 | - [Quais as aplicações do _Crivo de Eratóstenes_?](#quais-as-aplicações-do-crivo-de-eratóstenes) 10 | - [Quais são os passos do _Crivo de Eratóstenes_?](#quais-são-os-passos-do-crivo-de-eratóstenes) 11 | - [Qual o desempenho do _Crivo de Eratóstenes_?](#qual-o-desempenho-do-crivo-de-eratóstenes) 12 | 13 | ## O quê é o _Crivo de Eratóstenes_? 14 | 15 | O _Crivo de Eratóstenes_ é um método antigo e simples para encontrar todos os números primos menores que um determinado número natural. Esse método foi desenvolvido pelo matemático grego Eratóstenes de Cirene por volta do século III a.C. O algoritmo funciona de forma iterativamente removendo todos os números compostos do intervalo. 16 | 17 | ## Quais são as características do _Crivo de Eratóstenes_? 18 | 19 | - O _Crivo de Eratóstenes_ encontra todos os número primos em um intervalo. 20 | - O _Crivo de Eratóstenes_ é um algoritmo determinístico. 21 | - O _Crivo de Eratóstenes_ requer um espaço de memória auxiliar para funcionar. 22 | 23 | ## Quais as aplicações do _Crivo de Eratóstenes_? 24 | 25 | - **Algoritmos de Criptografia** - Alguns sistemas criptográficos modernos, como o RSA, dependem da dificuldade de fatorar números grandes em seus fatores primos. O _Crivo de Eratóstenes_ pode ser usado para gerar uma lista de números primos que podem ser usados como base para a geração de chaves criptográficas. 26 | - **Algoritmos de Fatoração** - Alguns algoritmos de fatoração, como o método da fatoração por tentativa, dependem da verificação de primalidade dos números para identificar seus fatores primos. O _Crivo de Eratóstenes_ pode ser usado para gerar uma lista de números primos que podem ser usados para acelerar a fatoração desses números. 27 | - **Algoritmos de Geração de Números Aleatórios** - Alguns algoritmos de geração de números aleatórios dependem da geração de números primos aleatórios. O Crivo de Eratóstenes pode ser usado para pré-computar uma lista de números primos e, em seguida, selecionar um número aleatório dessa lista para uso em algoritmos de geração de números aleatórios. 28 | 29 | ## Quais são os passos do _Crivo de Eratóstenes_? 30 | 31 | 1. Inicie com uma lista de números inteiros de 2 até o limite máximo desejado. 32 | 2. Marque o número 2 como primo e circule-o na lista. 33 | 3. Para cada número não marcado na lista, identifique-o como primo e circule-o, em seguida, marque todos os seus múltiplos como compostos (não primos) riscando-os da lista. 34 | 4. Continue o processo até que todos os números na lista tenham sido marcados como primos ou compostos. 35 | 5. A lista final conterá apenas os números primos menores que o limite máximo desejado. 36 | 37 | ## Qual o desempenho do _Crivo de Eratóstenes_? 38 | 39 | O desempenho do _Crivo de Eratóstenes_ depende do limite máximo desejado para a lista de primos. O algoritmo tem complexidade de `O(n log log n)`, onde n é o limite máximo desejado. 40 | -------------------------------------------------------------------------------- /math/sieve-eratosthenes/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = eratosthenes.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= --verbose 128 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /math/sieve-eratosthenes/c/main.c: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Pedro Henrique Penna 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //============================================================================== 12 | // Sieve of Eratosthenes 13 | //============================================================================== 14 | 15 | // Sieve of Eratosthenes. 16 | static void eratosthenes(unsigned *numbers, unsigned n) 17 | { 18 | // Initialize. 19 | for (unsigned i = 0; i < n; i++) { 20 | numbers[i] = i; 21 | } 22 | 23 | // Run sieve. 24 | for (unsigned i = 2; i < n; i++) { 25 | if (numbers[i] != 0) { 26 | for (unsigned j = i + i; j < n; j += i) { 27 | numbers[j] = 0; 28 | } 29 | } 30 | } 31 | } 32 | 33 | //============================================================================== 34 | // Test 35 | //============================================================================== 36 | 37 | // Tests Sieve of Eratosthenes. 38 | static void test(unsigned n, bool verbose) 39 | { 40 | double tstart = 0.0; 41 | double tend = 0.0; 42 | const double MICROSECS = ((CLOCKS_PER_SEC / 1000000.0)); 43 | unsigned *numbers = malloc(n * sizeof(unsigned)); 44 | 45 | // Fix random number generator seed 46 | // to have a determinist behavior across runs. 47 | srand(0); 48 | 49 | // Run. 50 | tstart = clock(); 51 | eratosthenes(numbers, n); 52 | tend = clock(); 53 | 54 | // Report time. 55 | printf("Sieve of Eratoesthenes: %2.lf us\n", (tend - tstart) / MICROSECS); 56 | 57 | if (verbose) { 58 | printf("Prime Numbers:\n"); 59 | for (unsigned i = 0; i < n; i++) { 60 | if (numbers[i] != 0) { 61 | printf("%u ", numbers[i]); 62 | } 63 | } 64 | printf("\n"); 65 | } 66 | 67 | free(numbers); 68 | } 69 | 70 | //============================================================================== 71 | // Usage 72 | //============================================================================== 73 | 74 | // Prints program usage and exits. 75 | static void usage(char *const argv[]) 76 | { 77 | printf("%s - Testing program for sieve of eratosthenes.\n", argv[0]); 78 | printf("Usage: %s [--verbose] \n", argv[0]); 79 | exit(EXIT_FAILURE); 80 | } 81 | 82 | //============================================================================== 83 | // Main 84 | //============================================================================== 85 | 86 | // Drives the test function. 87 | int main(int argc, char *const argv[]) 88 | { 89 | unsigned n = 0; 90 | bool verbose = false; 91 | 92 | // Check for missing arguments. 93 | if ((argc < 2) || (argc > 3)) { 94 | printf("Error: invalid number of arguments.\n", argc); 95 | usage(argv); 96 | } 97 | 98 | // Parse command line arguments. 99 | if (argc == 2) { 100 | sscanf(argv[1], "%u", &n); 101 | } else if ((argc == 3) && (!strcmp(argv[1], "--verbose"))) { 102 | sscanf(argv[2], "%u", &n); 103 | verbose = true; 104 | } else { 105 | printf("Error: invalid arguments.\n"); 106 | usage(argv); 107 | } 108 | 109 | // Run it! 110 | test(n, verbose); 111 | 112 | return (EXIT_SUCCESS); 113 | } 114 | -------------------------------------------------------------------------------- /searching/binary-search/README.md: -------------------------------------------------------------------------------- 1 | # Binary Search 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [About](#about) 8 | - [Properties](#properties) 9 | - [Algorithm](#algorithm) 10 | - [Performance](#performance) 11 | - [Further Reading](#further-reading) 12 | 13 | ## About 14 | 15 | Binary Search is a search algorithm that looks for a particular element in a sorted array. It works by repeatedly dividing the search interval in half and checking if the target element is in the middle of the current interval. If the desired element is smaller than the middle one, a recursive search is performed on the lower half of the array. If the desired element is greater than the element in the middle, a recursive search is performed on the upper half of the array. This process continues until the desired element is found, or there are no more elements to search. 16 | 17 | ## Properties 18 | 19 | - It is a Divide and Conquer algorithm. 20 | - It works only on sorted arrays. 21 | 22 | ## Algorithm 23 | 24 | 1. Consider as the initial search range, the full length of the input array. 25 | 2. If the search range is empty, stop. The target element is not in the input array. 26 | 3. Compare the target element with the element in the middle of the search range. 27 | 4. If the target element matches with the mid element, stop. The target element was found. 28 | 5. Else if the the target element is smaller than the mid element, take the sub-range to the left of the mid element as the new search range and go to Step 2. 29 | 6. Else if the target element is greater than the mid element, take the sub-range to the right of the mid element as the new search range and go to Step 2. 30 | 31 | ## Performance 32 | 33 | ### Best-Case 34 | 35 | The best-case scenario for the Binary Search algorithm occurs when the desired element is the first element considered. In this scenario, the algorithm has a constant cost of comparisons, in respect to the number of elements `n` in the array: 36 | 37 | - `O(1)` comparisons 38 | 39 | ### Worst-Case 40 | 41 | The worst case scenario for the Binary Search algorithm occurs when the desired element is not present in the input array. In this scenario, the algorithm has a logarithmic cost of comparisons, in respect to the number of elements `n` in the array: 42 | 43 | - `O(log₂ n)` comparisons 44 | 45 | ## Further Reading 46 | 47 | - [Wikipedia](https://en.wikipedia.org/wiki/Binary_search_algorithm) 48 | -------------------------------------------------------------------------------- /searching/binary-search/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Busca Binária 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é a Busca Binária?](#o-quê-é-a-busca-binária) 8 | - [Quais são as características da Busca Binária?](#quais-são-as-características-da-busca-binária) 9 | - [Qual é o algoritmo da Busca Binária?](#qual-é-o-algoritmo-da-busca-binária) 10 | - [Qual o desempenho da Busca Binária?](#qual-o-desempenho-da-busca-binária) 11 | - [Leitura Complementar](#leitura-complementar) 12 | 13 | ## O quê é a Busca Binária? 14 | 15 | A Busca Binária (_Binary Search_) é um algoritmo de busca que procura por um elemento desejado em um arranjo ordenado. O algoritmo funciona dividindo o arranjo no meio repetidamente e comparando o elemento no meio com o elemento procurado. Se o elemento procurado for menor que o elemento no meio, então uma busca recursiva é feita na metade inferior do arranjo. Se o elemento procurado for maior que o elemento no meio, então uma busca recursiva é feia na metade superior do arranjo. Esse processo continua, até que o elemento desejado seja encontrado ou então não haja mais elementos para serem pesquisados. 16 | 17 | ## Quais são as características da Busca Binária? 18 | 19 | - A Busca Binária é um algoritmo de Divisão e Conquista. 20 | - A Busca Binária funciona apenas em arranjos ordenados. 21 | - A Busca Binária não requer uma estrutura de dados auxiliar para funcionar. 22 | 23 | ## Qual é o algoritmo da Busca Binária? 24 | 25 | 1. Inicialmente, considere como intervalo de busca todo o arranjo de entrada. 26 | 2. Caso o intervalo de busca for vazio, pare. O elemento desejado não está no arranjo de entrada. 27 | 3. Compare o elemento desejado com o elemento do meio no intervalo de busca. 28 | 4. Se o elemento desejado for o que estiver no meio do intervalo de busca, pare. O elemento desejado foi encontrado. 29 | 5. Senão, se o elemento desejado for menor que o elemento no meio do intervalo de busca, considere o intervalo à esquerda do elemento do meio como o novo intervalo de busca e faça uma busca nesse novo intervalo (vá para o Passo 2). 30 | 6. Senão, se o elemento desejado for maior que o elemento no meio do intervalo de busca, considere o intervalo à direita do elemento do meio como novo intervalo de busca e faça uma busca nesse novo intervalo (vá para o Passo 2). 31 | 32 | ## Qual o desempenho da Busca Binária? 33 | 34 | ### Melhor Caso 35 | 36 | O melhor caso do algoritmo de Busca Binária ocorre quando o elemento procurado é o primeiro elemento considerado. Nesse cenário, o algoritmo tem um custo constante de comparações, em função do número de elementos `n` no arranjo: 37 | 38 | - `O(1)` comparações 39 | 40 | ### Pior Caso 41 | 42 | O pior caso do algoritmo de Busca Binária ocorre quando o elemento procurado não está presente no arranjo de entrada. Nesse cenário, o algoritmo tem um custo logarítmico de comparações, em função do número elementos `n` no arranjo: 43 | 44 | - `O(log₂ n)` comparações 45 | 46 | ## Leitura Complementar 47 | 48 | - [Wikipédia](https://pt.wikipedia.org/wiki/Pesquisa_bin%C3%A1ria) 49 | -------------------------------------------------------------------------------- /searching/binary-search/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = binary-search.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1048576" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /searching/binary-search/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "binary-search" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /searching/binary-search/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | use anyhow::Result; 4 | use rand::{ 5 | distributions::{uniform::SampleUniform, Uniform}, 6 | Rng, SeedableRng, 7 | }; 8 | use rand_chacha::ChaCha20Rng; 9 | use std::{env::args, time::Instant}; 10 | 11 | /// Finds an element in an array using Binary Search. 12 | fn binary_search(array: &[T], x: &T) -> usize { 13 | let mut low: usize = 0; 14 | let mut high: usize = array.len(); 15 | 16 | while low < high { 17 | let mid: usize = low + (high - low) / 2; 18 | 19 | // Found. 20 | if &array[mid] == x { 21 | return mid; 22 | } 23 | // Search on the left sub-array. 24 | else if x < &array[mid] { 25 | high = mid; 26 | } 27 | // Search on the right sub-array. 28 | else { 29 | low = mid + 1; 30 | } 31 | } 32 | 33 | usize::MAX 34 | } 35 | 36 | /// Initializes an array. 37 | fn init_array(array: &mut Vec, rng: &mut ChaCha20Rng, range: Uniform) 38 | where 39 | T: SampleUniform, 40 | { 41 | for _ in 0..array.capacity() { 42 | array.push(rng.sample(&range)) 43 | } 44 | } 45 | 46 | /// Tests Binary Search. 47 | fn test(length: usize, verbose: bool) { 48 | // Fix random number generator seed so that we have 49 | // a deterministic behavior across runs. 50 | let mut rng: ChaCha20Rng = ChaCha20Rng::seed_from_u64(0); 51 | let range: Uniform = Uniform::new(0, length); 52 | 53 | // Allocate and initialize array. 54 | let mut array: Vec = Vec::::with_capacity(length); 55 | init_array(&mut array, &mut rng, range); 56 | array.sort(); 57 | 58 | let key: &usize = &array[(rng.sample(&range))]; 59 | 60 | if verbose { 61 | println!("Input: {:?}", array); 62 | } 63 | 64 | let start: Instant = Instant::now(); 65 | let index: usize = binary_search(&array, key); 66 | let end: Instant = Instant::now(); 67 | 68 | // Report time. 69 | println!("Binary Search: {:.2?} us", (end - start).as_micros()); 70 | 71 | if verbose { 72 | let result: String = if index != usize::MAX { 73 | "found".to_string() 74 | } else { 75 | "not found".to_string() 76 | }; 77 | println!("Output: {:?}", result); 78 | } 79 | 80 | // Check solution. 81 | assert_eq!(key, &array[index]); 82 | } 83 | 84 | // Prints program usage. 85 | fn usage(args: &Vec) { 86 | println!("{} - Testing program for binary search.", args[0]); 87 | println!("Usage: {} [--verbose] ", args[0]); 88 | } 89 | 90 | fn main() -> Result<()> { 91 | let args: Vec = args().collect(); 92 | 93 | // Check for missing arguments. 94 | if (args.len() < 2) || (args.len() > 3) { 95 | usage(&args); 96 | anyhow::bail!("invalid number of arguments {:?}", args); 97 | } 98 | 99 | // Parse command line arguments. 100 | let (length, verbose): (usize, bool) = if args.len() == 2 { 101 | (args[1].parse()?, false) 102 | } else if (args.len() == 3) && (args[1] == "--verbose") { 103 | (args[2].parse()?, true) 104 | } else { 105 | anyhow::bail!("invalid argument"); 106 | }; 107 | 108 | test(length, verbose); 109 | 110 | Ok(()) 111 | } 112 | -------------------------------------------------------------------------------- /searching/exponential-search/README.md: -------------------------------------------------------------------------------- 1 | # Exponential Search 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [About](#about) 8 | - [Properties](#properties) 9 | - [Algorithm](#algorithm) 10 | - [Performance](#performance) 11 | - [Further Reading](#further-reading) 12 | 13 | ## What is Exponential Search? 14 | 15 | Exponential Search is a search algorithm created by Jon Bentley and Andrew Chi-Chih Yao in 1976 that is able to search for elements in an unlimited ordered array (an array that has an unknown upper limit). The algorithm consists of a combination of the Sequential Search and Binary Search algorithms, using the first algorithm to restrict the search space and the second algorithm to effectively search for the desired element. 16 | 17 | ## When to use Exponential Search? 18 | 19 | - Exponential Search should be used when you want to search in an unlimited ordered array (the upper limit of the array is unknown). 20 | - Exponential Search should be used when you estimate that the searched element is close to the beginning of the array. 21 | 22 | ## What are the properties of the Exponential Search? 23 | 24 | - Exponential Search is a hybrid algorithm, which combines the Sequential Search and Binary Search. 25 | - Exponential Search works only on ordered arrays. 26 | - Exponential Search works on unlimited arrays. 27 | - The performance of Exponential Search is very sensitive to the searched element. 28 | 29 | ## What is the Exponential Search algorithm? 30 | 31 | 1. Define the initial variables `i` as `1` and `n` as the length of the array. 32 | 2. While `i` is less than `n` and the element at index `i` is less than the searched element, double the value of `i`. 33 | 3. Perform a Binary Search in the range from `i/2` to `min(n, i)`. 34 | 4. Return the result of the Binary Search. 35 | 36 | ### Best-Case 37 | 38 | The best case of the Exponential Search algorithm occurs when the searched element is the first considered element. In this scenario, the algorithm has a constant cost of comparisons: 39 | 40 | - `O(1)` comparisons 41 | 42 | ### Worst-Case 43 | 44 | The worst case of the Exponential Search algorithm occurs when the searched element is not present in the input array. In this scenario, the algorithm has a logarithmic cost of comparisons, in relation to the number of elements n in the array: 45 | 46 | - `O(log₂ n)` comparisons 47 | 48 | ## Further Reading 49 | 50 | - [Wikipedia](https://en.wikipedia.org/wiki/Exponential_search) 51 | -------------------------------------------------------------------------------- /searching/exponential-search/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Busca Exponencial 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é a Busca Exponencial?](#o-quê-é-a-busca-exponencial) 8 | - [Quando usar a Busca Exponencial?](#quando-usar-a-busca-exponencial) 9 | - [Quais são as características da Busca Exponencial?](#quais-são-as-características-da-busca-exponencial) 10 | - [Qual é o algoritmo da Busca Exponencial?](#qual-é-o-algoritmo-da-busca-exponencial) 11 | - [Qual é o desempenho da Busca Exponencial?](#qual-é-o-desempenho-da-busca-exponencial) 12 | - [Leitura Complementar](#leitura-complementar) 13 | 14 | ## O quê é a Busca Exponencial? 15 | 16 | A Busca Exponencial (_Exponential Search_) é um algoritmo de busca criado por Jon Bentley e Andrew Chi-Chih Yao em 1976 que é capaz de procurar um elemento em um arranjo ordenado ilimitado (um arranjo que possui o limite superior desconhecido). O algoritmo consiste em uma combinação dos algoritmos de Busca Sequencial e Busca Binária, usando o primeiro algoritmo para restringir o espaço de busca e o segundo algoritmo para efetivamente procurar o elemento desejado. 17 | 18 | ## Quando usar a Busca Exponencial? 19 | 20 | - A Busca Exponencial deve ser usada quando deseja-se fazer uma busca em um arranjo ordenado ilimitado (o limite superior do arranjo é desconhecido). 21 | - A Busca exponencial é indicada quando estima-se que o elemento buscado está próximo do início do arranjo. Nesse caso, o desempenho médio do algoritmo é de `O(log₂ i)`, onde `i` é a posição do elemento buscado no arranjo de entrada. 22 | 23 | ## Quais são as características da Busca Exponencial? 24 | 25 | - A Busca Exponencial é um algoritmo híbrido, que combina a Busca Sequencial e a Busca Binária. 26 | - A Busca Exponencial funciona apenas em arranjos ordenados. 27 | - A Busca Exponencial funciona em arranjos ilimitados. 28 | - O desempenho da Busca Exponencial é muito sensível ao elemento buscado. 29 | 30 | ## Qual é o algoritmo da Busca Exponencial? 31 | 32 | 1. Defina a variável inicial `i` como `1` e `n` como o comprimento do arranjo. 33 | 2. Enquanto `i` for menor que `n` e o elemento no índice `i` for menor que o elemento procurado, dobre o valor de `i`. 34 | 3. Execute uma busca binária no intervalo de `i/2` até `min(n, i)`. 35 | 4. Retorne o resultado da busca binária. 36 | 37 | ## Qual é o desempenho da Busca Exponencial? 38 | 39 | ### Melhor Caso 40 | 41 | O melhor caso do algoritmo de Busca Exponencial ocorre quando o elemento procurado é o primeiro elemento considerado. Nesse cenário, o algoritmo tem um custo constante de comparações: 42 | 43 | - `O(1)` comparações 44 | 45 | ### Pior Caso 46 | 47 | O pior caso do algoritmo de Busca Exponencial ocorre quando o elemento procurado não está presente no arranjo de entrada. Nesse cenário, o algoritmo tem um custo logarítmico de comparações, em função do número elementos `n` no arranjo: 48 | 49 | - `O(log₂ n)` comparações 50 | 51 | ## Leitura Complementar 52 | 53 | - [Wikipédia](https://pt.wikipedia.org/wiki/Busca_exponencial) 54 | -------------------------------------------------------------------------------- /searching/exponential-search/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = exponential-search.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1048576" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /searching/exponential-search/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "exponential-search" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /searching/interpolation-search/README.md: -------------------------------------------------------------------------------- 1 | # Interpolation Search 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | 8 | ## What is the Interpolation Search? 9 | 10 | Interpolation Search is a search algorithm created by William Wesley Peterson in 1957 that can search for a specific element in an ordered array. The algorithm consists of a variation of the Binary Search algorithm, using an interpolation technique to reduce the number of iterations required to find the desired element. The interpolation method used can take into account the characteristics of the data in the search array, but often a linear interpolation method is chosen. 11 | 12 | ## When to use Interpolation Search? 13 | 14 | - Interpolation Search is indicated when it is known that there is a uniform distribution of elements in the search array. In this case, the average performance of the algorithm is `O(log₂ (log₂ n))` where n is the length of the search array. 15 | 16 | ## What are the characteristics of Interpolation Search? 17 | 18 | - Interpolation Search is a variation of Binary Search. 19 | - Interpolation Search only works on ordered arrays. 20 | - The performance of Interpolation Search is sensitive to the elements in the search array. 21 | 22 | ## What is the Interpolation Search algorithm? 23 | 24 | 1. Initially, consider the entire search array as the search interval. 25 | 2. If the search interval is empty, stop. The desired element is not in the search array. 26 | 3. Estimate the position of the desired element using an interpolation method (e.g. linear interpolation). 27 | 4. Compare the desired element with the element at the interpolated position. 28 | 5. If the desired element is the one at the interpolated position, stop. The desired element has been found. 29 | 6. Otherwise, if the desired element is greater than the element at the interpolated position, consider the interval to the left of the element at the interpolated position as the new search interval and search in this new interval (go to Step 2). 30 | 7. Otherwise, if the desired element is less than the element at the interpolated position, consider the interval to the right of the element at the interpolated position as the new search interval and search in this new interval (go to Step 2). 31 | 32 | ## What is the performance of Interpolation Search? 33 | 34 | ### Best-Case 35 | 36 | The best-case of the Interpolation Search algorithm occurs when the sought element is the first element considered. In this scenario, the algorithm has a constant cost of comparisons: 37 | 38 | - `O(1)` comparisons 39 | 40 | ## Worst-Case 41 | 42 | The worst-case of the Interpolation Search algorithm occurs when the search array does not have a uniform distribution of elements. In this scenario, the algorithm has a linear cost of comparisons, depending on length of the search array: 43 | 44 | - `O(n)` comparisons 45 | 46 | ## Further Reading 47 | 48 | - [Wikipedia](https://en.wikipedia.org/wiki/Interpolation_search) 49 | -------------------------------------------------------------------------------- /searching/interpolation-search/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Busca por Interpolação 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O que é a Busca por Interpolação?](#o-que-é-a-busca-por-interpolação) 8 | - [Quando usar a Busca por Interpolação?](#quando-usar-a-busca-por-interpolação) 9 | - [Quais são as características da Busca por Interpolação?](#quais-são-as-características-da-busca-por-interpolação) 10 | - [Qual o algoritmo da Busca por Interpolação?](#qual-o-algoritmo-da-busca-por-interpolação) 11 | - [Qual o desempenho da Busca por Interpolação?](#qual-o-desempenho-da-busca-por-interpolação) 12 | 13 | ## O que é a Busca por Interpolação? 14 | 15 | A Busca por Interpolação (_Interpolation Search_) é um algoritmo de busca criado por William Wesley Peterson em 1957 capaz de procurar um elemento específico em um arranjo ordenado. O algoritmo consiste em uma variação do algoritmo de Busca Binária, usando uma técnica de interpolação para reduzir o número de iterações necessárias para encontrar o elemento desejado. O método de interpolação empregado pode levar em consideração a característica dos dados no arranjo de busca, mas frequentemente um método de interpolação linear é escolhido. 16 | 17 | ## Quando usar a Busca por Interpolação? 18 | 19 | - A Busca por Interpolação é indicada quando sabe-se que existe uma distribuição uniforme dos elementos no arranjo de busca. Nesse caso, o desempenho médio do algoritmo é de `O(log₂ (log₂ n))` onde `n` é o comprimento do arranjo de busca. 20 | 21 | ## Quais são as características da Busca por Interpolação? 22 | 23 | - A Busca por Interpolação é uma variação da Busca Binária. 24 | - A Busca por Interpolação funciona apenas em arranjos ordenados. 25 | - O desempenho da Busca por Interpolação é sensível aos elementos no arranjo de busca. 26 | 27 | ## Qual o algoritmo da Busca por Interpolação? 28 | 29 | 1. Inicialmente, considere como intervalo de busca todo o arranjo de busca. 30 | 2. Caso o intervalo de busca for vazio, pare. O elemento desejado não está no arranjo de busca. 31 | 3. Estime a posição do elemento desejado usando um método de interpolação (ex: interpolação linear). 32 | 4. Compare o elemento desejado com o elemento na posição interpolada. 33 | 5. Se o elemento desejado for o que estiver na posição interpolada, pare. O elemento desejado foi encontrado. 34 | 6. Senão, se o elemento desejado for maior do que o elemento na posição interpolada, considere o intervalo à esquerda do elemento na posição interpolada como o novo intervalo de busca e faça uma busca nesse novo intervalo (vá para o Passo 2). 35 | 7. Senão, se o elemento desejado for maior do que o elemento na posição interpolada, considere o intervalo à direita do elemento na posição interpolada como o novo intervalo de busca e faça uma busca nesse novo intervalo (vá para o Passo 2). 36 | 37 | ## Qual o desempenho da Busca por Interpolação? 38 | 39 | ### Melhor Caso 40 | 41 | O melhor caso do algoritmo de Busca por Interpolação ocorre quando o elemento procurado é o primeiro elemento considerado. Nesse cenário, o algoritmo tem um custo constante de comparações: 42 | 43 | - `O(1)` comparações 44 | 45 | ### Pior Caso 46 | 47 | O pior caso do algoritmo de Busca por Interpolação ocorre quando o arranjo de busca não possui uma distribuição uniforme dos elementos. Nesse cenário, o algoritmo tem um custo linear de comparações, em função do número elementos `n` no arranjo: 48 | 49 | - `O(n)` comparações 50 | -------------------------------------------------------------------------------- /searching/interpolation-search/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = binary-search.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1048576" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /searching/interpolation-search/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "interpolation-search" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /searching/interpolation-search/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | use anyhow::Result; 4 | use rand::{ 5 | distributions::{uniform::SampleUniform, Uniform}, 6 | Rng, SeedableRng, 7 | }; 8 | use rand_chacha::ChaCha20Rng; 9 | use std::{env::args, time::Instant}; 10 | 11 | /// Finds an element in an array using Interpolation Search. 12 | fn interpolation_search( 13 | array: &[T], 14 | x: &T, 15 | interpolate: &dyn Fn(&T, &T, &T) -> usize, 16 | ) -> usize { 17 | let mut low: usize = 0; 18 | let mut high: usize = array.len(); 19 | 20 | while low < high { 21 | // Interpolate. 22 | let mid: usize = low + (high - low) * interpolate(x, &array[low], &array[high - 1]); 23 | 24 | // Found. 25 | if &array[mid] == x { 26 | return mid; 27 | } 28 | // Search on the left sub-array. 29 | else if x < &array[mid] { 30 | high = mid; 31 | } 32 | // Search on the right sub-array. 33 | else { 34 | low = mid + 1; 35 | } 36 | } 37 | 38 | usize::MAX 39 | } 40 | 41 | /// Initializes an array. 42 | fn init_array(array: &mut Vec, rng: &mut ChaCha20Rng, range: Uniform) 43 | where 44 | T: SampleUniform, 45 | { 46 | for _ in 0..array.capacity() { 47 | array.push(rng.sample(&range)) 48 | } 49 | } 50 | 51 | /// Tests Interpolation Search. 52 | fn test(length: usize, verbose: bool) { 53 | // Fix random number generator seed so that we have 54 | // a deterministic behavior across runs. 55 | let mut rng: ChaCha20Rng = ChaCha20Rng::seed_from_u64(0); 56 | let range: Uniform = Uniform::new(0, length); 57 | 58 | // Allocate and initialize array. 59 | let mut array: Vec = Vec::::with_capacity(length); 60 | init_array(&mut array, &mut rng, range); 61 | array.sort(); 62 | 63 | let key: &usize = &array[(rng.sample(&range))]; 64 | 65 | if verbose { 66 | println!("Input: {:?}", array); 67 | } 68 | 69 | let start: Instant = Instant::now(); 70 | let index: usize = interpolation_search(&array, key, &|x, low, high| (x - low) / (high - low)); 71 | let end: Instant = Instant::now(); 72 | 73 | // Report time. 74 | println!("Interpolation Search: {:.2?} us", (end - start).as_micros()); 75 | 76 | if verbose { 77 | let result: String = if index != usize::MAX { 78 | "found".to_string() 79 | } else { 80 | "not found".to_string() 81 | }; 82 | println!("Output: {:?}", result); 83 | } 84 | 85 | // Check solution. 86 | assert_eq!(key, &array[index]); 87 | } 88 | 89 | // Prints program usage. 90 | fn usage(args: &Vec) { 91 | println!("{} - Testing program for interpolation search.", args[0]); 92 | println!("Usage: {} [--verbose] ", args[0]); 93 | } 94 | 95 | fn main() -> Result<()> { 96 | let args: Vec = args().collect(); 97 | 98 | // Check for missing arguments. 99 | if (args.len() < 2) || (args.len() > 3) { 100 | usage(&args); 101 | anyhow::bail!("invalid number of arguments {:?}", args); 102 | } 103 | 104 | // Parse command line arguments. 105 | let (length, verbose): (usize, bool) = if args.len() == 2 { 106 | (args[1].parse()?, false) 107 | } else if (args.len() == 3) && (args[1] == "--verbose") { 108 | (args[2].parse()?, true) 109 | } else { 110 | anyhow::bail!("invalid argument"); 111 | }; 112 | 113 | test(length, verbose); 114 | 115 | Ok(()) 116 | } 117 | -------------------------------------------------------------------------------- /searching/linear-search/README.md: -------------------------------------------------------------------------------- 1 | # Linear Search 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [About](#about) 8 | - [Properties](#properties) 9 | - [Algorithm](#algorithm) 10 | - [Performance](#performance) 11 | - [Further Reading](#further-reading) 12 | 13 | ## About 14 | 15 | Linear Search or Sequential search is a search algorithm that finds a particular 16 | element in an input list or array by iterating through each element one at a 17 | time and checking if it is the element searched for. 18 | 19 | ## Properties 20 | 21 | - Linear Search works on lists and arrays. 22 | - Linear Search works on unordered data. 23 | - Linear Search does not require auxiliary data structures to work. 24 | - The performance of Linear Search is impacted by how the input data is layout 25 | on the list or array. 26 | 27 | ## Algorithm 28 | 29 | 1. Initialize a variable called `position` to `-1`. This variable will be used 30 | to store the position of the element being searched for. 31 | 2. Enter a loop that iterates through each element in the list or array. 32 | 3. In the loop, compare the current element with the element being searched for. 33 | 4. If the current element is equal to the element being searched for, set the 34 | `position` variable to the current index and break out of the loop. 35 | 5. After exiting the loop, check the element of the `position` variable. If it 36 | is still `-1`, the element was not found in the list or array. If it is not 37 | `-1`, the element was found at the position stored in the `position` variable. 38 | 39 | ## Performance 40 | 41 | ### Best-Case 42 | 43 | The best-case performance for Linear Search happens when the element being 44 | searched for is at the first position in the input list or array. In this 45 | scenario, Linear Search presents a takes a constant number of comparisons, in 46 | respect to the number of elements `n` in the input list or array: 47 | 48 | - `O(1)` comparisons 49 | 50 | ### Worst-Case 51 | 52 | The worst-case performance for Linear Search happens when the element being 53 | search for is at the first position in the input array or list. In this 54 | scenario, Linear Search takes a linear number of comparisons, in respect to the 55 | number of elements `n` in the input list or array: 56 | 57 | - `O(n)` comparisons 58 | 59 | ## Further Reading 60 | 61 | - [Wikipedia](https://en.wikipedia.org/wiki/Linear_search) 62 | -------------------------------------------------------------------------------- /searching/linear-search/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Busca Sequencial 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é a Busca Sequencial?](#o-quê-é-a-busca-sequencial) 8 | - [Quais são as características da Busca Sequencial?](#quais-são-as-características-da-busca-sequencial) 9 | - [Qual é o algoritmo da Busca Sequencial?](#qual-é-o-algoritmo-da-busca-sequencial) 10 | - [Qual o desempenho da Busca Sequencial?](#qual-o-desempenho-da-busca-sequencial) 11 | - [Leitura Complementar](#leitura-complementar) 12 | 13 | ## O quê é a Busca Sequencial? 14 | 15 | A Busca Sequencial (_Sequential Search_) ou Busca Linear (_Linear Search_) é um algoritmo de busca que encontra um elemento específico em uma lista ou arranjo, iterando por um elemento de cada vez e verificando se aquele elemento é o do elemento procurado. 16 | 17 | ## Quais são as características da Busca Sequencial? 18 | 19 | - A Busca Sequencial funciona em listas e arranjos. 20 | - A Busca Sequencial funciona em dados não ordenados. 21 | - A Busca Sequencial não requer uma estrutura de dados auxiliar para funcionar. 22 | - O desempenho da Busca Sequencial é impactado pela forma como os dados de entrada estão dispostos na lista ou arranjo. 23 | 24 | ## Qual é o algoritmo da Busca Sequencial? 25 | 26 | 1. Inicialize uma variável chamada `posição` com `-1`. Essa variável será usada para armazenar a posição do elemento procurado. 27 | 2. Inicie um laço que itere através de cada elemento na lista ou arranjo. 28 | 3. Dentro do laço, compare o elemento atual com o elemento procurado. 29 | 4. Se o elemento atual for igual ao elemento procurado, defina a variável `posição` como o índice atual e saia do laço. 30 | 5. Depois que o laço terminar, verifique o elemento da variável `posição`. Se ela ainda for `-1`, o elemento não foi encontrado na lista ou arranjo. Se não for `-1`, o elemento foi encontrado na posição armazenada na variável `posição`. 31 | 32 | ## Qual o desempenho da Busca Sequencial? 33 | 34 | ### Melhor Caso 35 | 36 | O desempenho do melhor caso para o algoritmo de Busca Sequencial acontece quando o elemento buscado está na primeira posição do arranjo ou lista de entrada. Nesse cenário, a Busca Sequencial apresenta um custo constante de comparações, em função do número de elementos `n` na lista ou arranjo de entrada: 37 | 38 | - `O(1)` comparações 39 | 40 | ### Pior Caso 41 | 42 | O desempenho do pior caso para o algoritmo de Busca Sequencial acontece quando o elemento buscado está na última posição do arranjo ou lista de entrada. Nesse cenário, a Busca Sequencial apresenta um custo linear de comparações, em função do número de elementos `n` na lista ou arranjo de entrada: 43 | 44 | - `O(n)` 45 | 46 | ## Leitura Complementar 47 | 48 | - [Wikipédia](https://pt.wikipedia.org/wiki/Busca_linear) 49 | -------------------------------------------------------------------------------- /searching/linear-search/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = linear-search.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1048576" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /searching/linear-search/c/main.c: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // Type of elements that are stored in the array. 12 | typedef int type_t; 13 | 14 | // Searches for an element in an array using Linear Search. 15 | static size_t linear_search(const type_t array[], size_t length, type_t element) 16 | { 17 | // Traverses the input array looking for the given key. 18 | for (size_t i = 0; i < length; i++) { 19 | // Found. 20 | if (array[i] == element) { 21 | return (i); 22 | } 23 | } 24 | 25 | return ((size_t)-1); 26 | } 27 | 28 | // Initializes an array. 29 | static void initialize_array(type_t array[], size_t length) 30 | { 31 | for (size_t i = 0; i < length; i++) { 32 | array[i] = (type_t)(rand() % length); 33 | } 34 | } 35 | 36 | // Tests Linear Search. 37 | static void test(size_t length, bool verbose) 38 | { 39 | double tstart = 0.0; 40 | double tend = 0.0; 41 | type_t *array = NULL; 42 | const double MICROSECS = ((CLOCKS_PER_SEC / 1000000.0)); 43 | size_t index = (size_t)-1; 44 | type_t key = 0; 45 | 46 | // Fix random number generator seed 47 | // to have a determinist behavior across runs. 48 | srand(0); 49 | 50 | // Allocate an initialize array. 51 | array = malloc(length * sizeof(type_t)); 52 | assert(array != NULL); 53 | initialize_array(array, length); 54 | 55 | key = array[(size_t)rand() % length]; 56 | 57 | if (verbose) { 58 | printf("Search Key: %d\n", key); 59 | } 60 | 61 | // Search in the array. 62 | tstart = clock(); 63 | index = linear_search(array, length, key); 64 | tend = clock(); 65 | 66 | // Report time. 67 | printf("Linear Search: %2.lf us\n", (tend - tstart) / MICROSECS); 68 | 69 | if (verbose) { 70 | printf("Output: %s\n", (index != (size_t)-1) ? "found" : "not found"); 71 | } 72 | 73 | // Release array. 74 | free(array); 75 | } 76 | 77 | // Prints program usage and exits. 78 | static void usage(char *const argv[]) 79 | { 80 | printf("%s - Testing program for linear search.\n", argv[0]); 81 | printf("Usage: %s [--verbose] \n", argv[0]); 82 | exit(EXIT_FAILURE); 83 | } 84 | 85 | // Drives the test function. 86 | int main(int argc, char *const argv[]) 87 | { 88 | size_t length = 0; 89 | bool verbose = false; 90 | 91 | // Check for missing arguments. 92 | if ((argc < 2) || (argc > 3)) { 93 | printf("Error: invalid number of arguments.\n"); 94 | usage(argv); 95 | } 96 | 97 | // Parse command line arguments. 98 | if (argc == 2) { 99 | sscanf(argv[1], "%zu", &length); 100 | } else if ((argc == 3) && (!strcmp(argv[1], "--verbose"))) { 101 | sscanf(argv[2], "%zu", &length); 102 | verbose = true; 103 | } else { 104 | printf("Error: invalid arguments.\n"); 105 | usage(argv); 106 | } 107 | 108 | // Run it! 109 | test(length, verbose); 110 | 111 | return (EXIT_SUCCESS); 112 | } 113 | -------------------------------------------------------------------------------- /searching/linear-search/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "linear-search" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /searching/linear-search/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | use anyhow::Result; 4 | use rand::{ 5 | distributions::{uniform::SampleUniform, Uniform}, 6 | Rng, SeedableRng, 7 | }; 8 | use rand_chacha::ChaCha20Rng; 9 | use std::{cmp::Eq, env::args, time::Instant}; 10 | 11 | /// Finds an element in an array using Linear Search. 12 | fn linear_search(array: &[T], x: &T) -> usize { 13 | // Traverse the array searching for the target element. 14 | for i in 0..array.len() { 15 | // Found. 16 | if &array[i] == x { 17 | return i; 18 | } 19 | } 20 | 21 | usize::MAX 22 | } 23 | 24 | /// Initializes an array. 25 | fn init_array(array: &mut Vec, rng: &mut ChaCha20Rng, range: Uniform) 26 | where 27 | T: SampleUniform, 28 | { 29 | for _ in 0..array.capacity() { 30 | array.push(rng.sample(&range)) 31 | } 32 | } 33 | 34 | /// Tests Linear Search. 35 | fn test(length: usize, verbose: bool) { 36 | // Fix random number generator seed so that we have 37 | // a deterministic behavior across runs. 38 | let mut rng: ChaCha20Rng = ChaCha20Rng::seed_from_u64(0); 39 | let range: Uniform = Uniform::new(0, length); 40 | 41 | // Allocate and initialize array. 42 | let mut array: Vec = Vec::::with_capacity(length); 43 | init_array(&mut array, &mut rng, range); 44 | 45 | let key: &usize = &array[(rng.sample(&range))]; 46 | 47 | if verbose { 48 | println!("Input: {:?}", array); 49 | } 50 | 51 | let start: Instant = Instant::now(); 52 | let index: usize = linear_search(&array, key); 53 | let end: Instant = Instant::now(); 54 | 55 | // Report time. 56 | println!("Linear Search: {:.2?} us", (end - start).as_micros()); 57 | 58 | if verbose { 59 | let result: String = if index != usize::MAX { 60 | "found".to_string() 61 | } else { 62 | "not found".to_string() 63 | }; 64 | println!("Output: {:?}", result); 65 | } 66 | 67 | // Check solution. 68 | assert_eq!(key, &array[index]); 69 | } 70 | 71 | // Prints program usage. 72 | fn usage(args: &Vec) { 73 | println!("{} - Testing program for linear search.", args[0]); 74 | println!("Usage: {} [--verbose] ", args[0]); 75 | } 76 | 77 | fn main() -> Result<()> { 78 | let args: Vec = args().collect(); 79 | 80 | // Check for missing arguments. 81 | if (args.len() < 2) || (args.len() > 3) { 82 | usage(&args); 83 | anyhow::bail!("invalid number of arguments {:?}", args); 84 | } 85 | 86 | // Parse command line arguments. 87 | let (length, verbose): (usize, bool) = if args.len() == 2 { 88 | (args[1].parse()?, false) 89 | } else if (args.len() == 3) && (args[1] == "--verbose") { 90 | (args[2].parse()?, true) 91 | } else { 92 | anyhow::bail!("invalid argument"); 93 | }; 94 | 95 | test(length, verbose); 96 | 97 | Ok(()) 98 | } 99 | -------------------------------------------------------------------------------- /sorting/bubble-sort/README.md: -------------------------------------------------------------------------------- 1 | # Bubble Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | Bubble Sort is a sorting algorithm that works by repeatedly swapping pair of 8 | adjacent elements in the input array that are relatively out-of-order. The 9 | algorithm takes this name for the way that large elements "bubble up" to the end 10 | of the array. 11 | 12 | Bubble Sort presents a poor performance, when compared to other sorting 13 | algorithms. Still, it is simple to understand and thus it is often used to motivate 14 | the study of other sorting algorithms. 15 | 16 | ## Algorithm 17 | 18 | 1. Traverse the input array, from the begin towards the end. 19 | 2. For each element that is considered, check if the following element is a smaller one. 20 | 3. If that is the case, swap the two elements. 21 | 4. When done traversing the array, check if any pair of elements were swapped. 22 | If that is the case, go back to Step 1. 23 | 5. The array is sorted. 24 | 25 | ## Performance 26 | 27 | - Best-Case: $O(n^2)$ comparisons, $O(1)$ swaps 28 | - Worst-Case: $O(n^2)$ comparisons, $O(n^2)$ swaps 29 | 30 | ## Further Reading 31 | 32 | - [Desenvolvendo Software](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/bubble-sort.html) (Portuguese) 33 | - [Wikipedia](https://en.wikipedia.org/wiki/Bubble_sort) 34 | -------------------------------------------------------------------------------- /sorting/bubble-sort/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Bubble Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o _Bubble Sort_?](#o-quê-é-o-bubble-sort) 8 | - [Quais são as características do _Bubble Sort_?](#quais-são-as-características-do-bubble-sort) 9 | - [Qual é o algoritmo do _Bubble Sort_?](#qual-é-o-algoritmo-do-bubble-sort) 10 | - [Qual é o desempenho do _Bubble Sort_?](#qual-é-o-desempenho-do-bubble-sort) 11 | - [Leitura Complementar](#leitura-complementar) 12 | 13 | ## O quê é o _Bubble Sort_? 14 | 15 | O _Bubble Sort_ (Ordenação por Bolha) é um algoritmo de ordenação que funciona trocando repetidamente de posição, os elementos adjacentes em um arranjo que estão fora de ordem entre si. O algoritmo leva esse nome por "borbulhar" os maiores elementos para o final do arranjo. 16 | 17 | O _Bubble Sort_ apresenta um desempenho ruim, quando comparado à outros algoritmos de ordenação. No entanto, por ser de simples compreensão, é frequentemente usado para motivar o estudo de outros algoritmos de ordenação. 18 | 19 | ## Quais são as características do _Bubble Sort_? 20 | 21 | - O _Bubble Sort_ é um algoritmo iterativo. 22 | - O _Bubble Sort_ é um algoritmo de ordenação por comparação. 23 | - O _Bubble Sort_ é um algoritmo de ordenação estável. 24 | - O desempenho do algoritmo não é sensível aos dados de entrada. 25 | 26 | ## Qual é o algoritmo do _Bubble Sort_? 27 | 28 | 1. Percorra a o arranjo de entrada, do início ao fim. 29 | 2. Para cada elemento considerado, verifique se o elemento subsequente no arranjo é menor. 30 | 3. Em caso afirmativo, troque os dois elementos de posição no arranjo. 31 | 4. Ao terminar de percorrer o arranjo, verifique se algum elemento trocou de posição. Em caso afirmativo, volte ao Passo 1. 32 | 5. O arranjo está ordenado. 33 | 34 | ## Qual é o desempenho do _Bubble Sort_? 35 | 36 | O _Bubble Sort_ não é um algoritmo de ordenação indicado para a ordenação de grandes conjuntos de dados. 37 | 38 | ### Pior Caso 39 | 40 | O pior caso para o algoritmo _Bubble Sort_ ocorre quando o arranjo de entrada está ordenado de forma inversa. Nessa situação, o algoritmo tem um custo quadrático de comparações e trocas, em função do número de elementos a serem ordenados: 41 | 42 | - `O(n²)` comparações 43 | - `O(n²)` trocas 44 | 45 | ### Melhor Caso 46 | 47 | O melhor caso para o algoritmo _Bubble Sort_ ocorre quando o arranjo de entrada já está ordenado. Nessa situação, o algoritmo tem um custo linear de comparações e um custo constante de trocas, em função do número de elementos a serem ordenados: 48 | 49 | - `O(n)` comparações 50 | - `O(1)` trocas 51 | 52 | ## Leitura Complementar 53 | 54 | - [Desenvolvendo Software | Bubble Sort](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/bubble-sort.html) 55 | -------------------------------------------------------------------------------- /sorting/bubble-sort/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = bubble-sort.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /sorting/bubble-sort/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "bubble-sort" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /sorting/bubble-sort/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | use anyhow::Result; 4 | use rand::{ 5 | distributions::{uniform::SampleUniform, Uniform}, 6 | Rng, SeedableRng, 7 | }; 8 | use rand_chacha::ChaCha20Rng; 9 | use std::{env::args, time::Instant}; 10 | 11 | /// Sorts an array using Bubble Sort. 12 | fn bubble_sort(array: &mut [T]) { 13 | // Keep sorting while elements are swapped. 14 | loop { 15 | let mut changed: bool = false; 16 | 17 | // Bubble up largest element. 18 | for i in 1..array.len() { 19 | if array[i - 1] > array[i] { 20 | changed = true; 21 | array.swap(i - 1, i); 22 | } 23 | } 24 | 25 | // Done sorting. 26 | if !changed { 27 | break; 28 | } 29 | } 30 | } 31 | 32 | /// Initializes an array. 33 | fn init_array(array: &mut Vec, rng: &mut ChaCha20Rng, range: Uniform) 34 | where 35 | T: SampleUniform, 36 | { 37 | for _ in 0..array.capacity() { 38 | array.push(rng.sample(&range)) 39 | } 40 | } 41 | 42 | /// Checks if an array is sorted. 43 | fn is_sorted(array: &[T]) -> bool { 44 | for i in 1..array.len() { 45 | if array[i - 1] > array[i] { 46 | return false; 47 | } 48 | } 49 | true 50 | } 51 | 52 | /// Tests Bubble Sort. 53 | fn test(length: usize, verbose: bool) { 54 | // Fix random number generator seed so that we have 55 | // a deterministic behavior across runs. 56 | let mut rng: ChaCha20Rng = ChaCha20Rng::seed_from_u64(0); 57 | let range: Uniform = Uniform::new(0, length); 58 | 59 | // Allocate and initialize array. 60 | let mut array: Vec = Vec::::with_capacity(length); 61 | init_array(&mut array, &mut rng, range); 62 | 63 | if verbose { 64 | println!("Input: {:?}", array); 65 | } 66 | 67 | let start: Instant = Instant::now(); 68 | bubble_sort(&mut array); 69 | let end: Instant = Instant::now(); 70 | 71 | // Report time. 72 | println!("Bubble Sort: {:.2?} us", (end - start).as_micros()); 73 | 74 | // Check if array is sorted. 75 | assert_eq!(is_sorted(&array), true); 76 | 77 | if verbose { 78 | println!("Output: {:?}", array); 79 | } 80 | } 81 | 82 | // Prints program usage. 83 | fn usage(args: &Vec) { 84 | println!("{} - Testing program for bubble sort.", args[0]); 85 | println!("Usage: {} [--verbose] ", args[0]); 86 | } 87 | 88 | fn main() -> Result<()> { 89 | let args: Vec = args().collect(); 90 | 91 | // Check for missing arguments. 92 | if (args.len() < 2) || (args.len() > 3) { 93 | usage(&args); 94 | anyhow::bail!("invalid number of arguments {:?}", args); 95 | } 96 | 97 | // Parse command line arguments. 98 | let (length, verbose): (usize, bool) = if args.len() == 2 { 99 | (args[1].parse()?, false) 100 | } else if (args.len() == 3) && (args[1] == "--verbose") { 101 | (args[2].parse()?, true) 102 | } else { 103 | anyhow::bail!("invalid argument"); 104 | }; 105 | 106 | test(length, verbose); 107 | 108 | Ok(()) 109 | } 110 | -------------------------------------------------------------------------------- /sorting/counting-sort/README.md: -------------------------------------------------------------------------------- 1 | # Counting Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | Counting Sort is an integer sorting algorithm devised by Harold Seward in 1954. 8 | It works by building a cumulative histogram of the keys in the input array, and 9 | then using that histogram to construct a sorted output array. 10 | 11 | In its classical definition, Counting Sort assumes that keys have non-negative 12 | values and the value of the maximum key is known in advance. Counting Sort is 13 | generally used as a sub-routine for other non-comparison sorting methods such as 14 | Radix Sort and Bucket Sort. 15 | 16 | ## Algorithm 17 | 18 | 1. Build the cumulative histogram $h$ of the keys in the input array. In this 19 | auxiliary data structure, the first bin gives the frequency of keys with value 20 | 0, the second bin gives the frequency of keys with value 1 plus the value of 21 | stored in the previous bin, and so on. 22 | 2. Construct a sorted output array using the cumulative histogram to determine 23 | the right position of elements. For instance, let $x$ bee an arbitrary element 24 | in the input array that has a key $k$, and $h(k)$ be the cumulative frequency 25 | for key $k$. Thus, $x$ should be placed in the output array in the range from 26 | $h(k)$ to $h(k+1)$. 27 | 28 | ## Performance 29 | 30 | - Best-Case: $O(n + k)$ 31 | - Worst-Case: $O(n + k)$ 32 | 33 | ## Further Reading 34 | 35 | - [Desenvolvendo Software](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/counting-sort.html) (Portuguese) 36 | - [Wikipedia](https://en.wikipedia.org/wiki/Counting_sort) 37 | -------------------------------------------------------------------------------- /sorting/counting-sort/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Counting Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o _Counting Sort_?](#o-quê-é-o-counting-sort) 8 | - [Quais são as características do _Counting Sort_?](#quais-são-as-características-do-counting-sort) 9 | - [Qual é o algoritmo do _Counting Sort_?](#qual-é-o-algoritmo-do-counting-sort) 10 | - [Qual é o desempenho do _Counting Sort_?](#qual-é-o-desempenho-do-counting-sort) 11 | - [Leitura Complementar](#leitura-complementar) 12 | 13 | ## O quê é o _Counting Sort_? 14 | 15 | O _Counting Sort_ (Ordenação por Contagem) é um algoritmo de ordenação de inteiros criado por Harold Seward em 1954. Ele é um algoritmo de Programação Dinâmica, que funciona construindo um histograma cumulativo das chaves do arranjo de entrada e o usando essa estrutura para construir um arranjo de saída ordenado. 16 | 17 | Apesar de possui um desempenho assintótico eficiente, o _Counting Sort_ é 18 | geralmente usado como sub-rotina em outros métodos de ordenação não 19 | comparativos, como o _Radix Sort_ e o _Bucket Sort_. 20 | 21 | ## Quais são as características do _Counting Sort_? 22 | 23 | - O _Counting Sort_ é um algoritmo iterativo. 24 | - O _Counting Sort_ é um algoritmo de ordenação de inteiros. 25 | - O _Counting Sort_ é um algoritmo de ordenação estável. 26 | - O desempenho do algoritmo _Counting Sort_ é pouco sensível aos dados de entrada. 27 | - O _Counting Sort_ necessita de uma estrutura de dados auxiliar para funcionar. 28 | 29 | ## Qual é o algoritmo do _Counting Sort_? 30 | 31 | 1. Crie um arranjo auxiliar `H` de tamanho igual à maior chave presente no arranjo original `A`. 32 | 2. Conte o número de ocorrências de cada elemento em `A` e armazene essa contagem no arranjo auxiliar `H`. Nesse arranjo auxiliar, a primeira posição dá a frequência de elementos de valor `0` em `A`, a segunda posição dá a frequência de elementos de valor `1` em `A` e assim por diante. 33 | 3. Percorra o arranjo auxiliar `H` para criar o histograma cumulativo de cada elemento de `A`. Para tanto, acumule o valor da frequência do elemento `i + 1` com a frequência do elemento `i`. 34 | 4. Use o arranjo `H` para construir um arranjo de saída ordenado. Para tanto, se `x` é um elemento no arranjo `A` que possui uma frequência cumulativa `H(x)`, então `x` deve ser colocado no arranjo de saída entre a posição `H(x)` e `H(x + 1)`. 35 | 36 | ## Qual é o desempenho do _Counting Sort_? 37 | 38 | O desempenho do _Counting Sort_ é pouco sensível a entrada. Por esse motivo, o desempenho assintótico do algoritmo é linear tanto para o pior quanto melhor caso. Se `n` é o número de elementos no arranjo de entrada e `k` é o valor da maior chave nesse arranjo, o desempenho do _Counting Sort_ é: 39 | 40 | - `O(n + k)` operações inteiras 41 | 42 | ## Leitura Complementar 43 | 44 | - [Desenvolvendo Software | Counting Sort](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/counting-sort.html) 45 | -------------------------------------------------------------------------------- /sorting/counting-sort/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = counting-sort.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /sorting/counting-sort/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "counting-sort" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /sorting/heapsort/README.md: -------------------------------------------------------------------------------- 1 | # Heapsort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /sorting/heapsort/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Heapsort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O que é o Heapsort?](#o-que-é-o-heapsort) 8 | - [Quais são as características do Heapsort?](#quais-são-as-características-do-heapsort) 9 | - [Qual é o algoritmo de Heapsort?](#qual-é-o-algoritmo-de-heapsort) 10 | - [Qual é o desempenho do Heapsort?](#qual-é-o-desempenho-do-heapsort) 11 | 12 | ## O que é o Heapsort? 13 | 14 | O Heapsort (Ordenação por Heap) é um algoritmo de ordenação que utiliza uma estrutura de dados Heap Binária para ordenar um arranjo de elementos. A ideia central do algoritmo se resume a construir uma heap de máximo a partir do arranjo desordenado, e, em seguida, trocar o primeiro elemento com o último e manter a propriedade de heap máxima para os elementos restantes. Esse processo é repetido até que todos os elementos do arranjo estejam ordenados. 15 | 16 | ## Quais são as características do Heapsort? 17 | 18 | - O Heapsort é um algoritmo iterativo. 19 | - O Heapsort é um algoritmo de ordenação por comparação. 20 | - O Heapsort é um algoritmo de ordenação estável. 21 | - O desempenho do algoritmo não é sensível aos dados de entrada. 22 | 23 | ## Qual é o algoritmo de Heapsort? 24 | 25 | 1. Construa uma heap de máximo a partir do arranjo de entrada. 26 | 2. Troque do primeiro elemento com o último elemento do arranjo. 27 | 3. Corrija a propriedade de heap máximo, com os `N-1` elementos restantes no arranjo. 28 | 4. Repetição dos Passos 2 e 3 até que todos os elementos estejam ordenados. Após cada iteração, o tamanho da heap de máximo é reduzido em 1. 29 | 5. O arranjo está ordenado. 30 | 31 | ## Qual é o desempenho do Heapsort? 32 | 33 | O desempenho do Heapsort não é impactado pela disposição inicial dos elementos no arranjo de entrada. Por esse motivo, o algoritmo apresenta um custo super-linear no pior e melhor caso, em função do comprimento `n` do arranjo de entrada: 34 | 35 | - `O(n log₂ n)` comparações 36 | -------------------------------------------------------------------------------- /sorting/heapsort/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = heapsort.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /sorting/insertion-sort/README.md: -------------------------------------------------------------------------------- 1 | # Insertion Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | Insertion sort is a comparison sorting algorithm that works similar to the way 8 | that some people sort cards in a bridge hand. When a new card should be inserted 9 | in the bridge hand, the player compares that new card with the others, to 10 | determine the right point of insertion. 11 | 12 | ## Algorithm 13 | 14 | 1. Partition the input array in two: (i) a sub-array $A$ that initially contains 15 | only the first element of the input array; and (ii) a sub-array $B$ that 16 | initially contains all the remainder elements. 17 | 2. Take the first element of sub-array $B$ and call it $x$. 18 | 3. Search the sub-array $A$ for the insertion point for $x$, from right to left. 19 | 4. Shift one position to the right, all elements in the sub-array $A$ that are 20 | left to the of the insertion point. 21 | 5. Insert $x$ in the insertion position in $A$. 22 | 6. If sub-array $B$ is not empty, go to Step 2. 23 | 7. Return sub-array $A$, which contains all elements from the original array 24 | sorted. 25 | 26 | ## Performance 27 | 28 | - Best-Case: $O(n)$ comparisons, $O(1)$ trocas. 29 | - Worst-Case: $O(n^2)$ comparisons, $O(n^2)$ swaps. 30 | 31 | ## Further Reading 32 | 33 | - [Desenvolvendo Software](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/insertion-sort.html) 34 | - [Wikipédia](https://en.wikipedia.org/wiki/Insertion_sort) 35 | -------------------------------------------------------------------------------- /sorting/insertion-sort/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Insertion Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o _Insertion Sort_?](#o-quê-é-o-insertion-sort) 8 | - [Quais são as características do _Insertion Sort_?](#quais-são-as-características-do-insertion-sort) 9 | - [Qual é o algoritmo de _Insertion Sort_?](#qual-é-o-algoritmo-de-insertion-sort) 10 | - [Qual é o desempenho do _Insertion Sort_?](#qual-é-o-desempenho-do-insertion-sort) 11 | - [Leitura Complementar](#leitura-complementar) 12 | 13 | ## O quê é o _Insertion Sort_? 14 | 15 | O _Insertion Sort_ (Ordenação por Inserção) é um algoritmo de ordenação que funciona de forma similar ao modo como algumas pessoas ordenam cartas de um baralho, quando estão jogando. Ao adicionar uma nova carta a uma mão de cartas ordenadas, o jogador compara a nova carta com todas as demais cartas em sua mão, para determinar o ponto de inserção adequado. 16 | 17 | ## Quais são as características do _Insertion Sort_? 18 | 19 | - O _Insertion Sort_ é um algoritmo iterativo. 20 | - O _Insertion Sort_ é um algoritmo de ordenação por comparação. 21 | - O _Insertion Sort_ é um algoritmo de ordenação estável. 22 | - O desempenho do algoritmo _Insertion Sort_ é muito sensível aos dados de entrada. 23 | - O _Insertion Sort_ necessita de uma estrutura de dados auxiliar para funcionar. 24 | 25 | ## Qual é o algoritmo de _Insertion Sort_? 26 | 27 | 1. Particione o arranjo de entrada em dois: 28 | - Um sub-arranjo `A` que inicialmente contém apenas o primeiro elemento do arranjo original. 29 | - Um sub-arranjo `B` que inicialmente contém todos os demais elementos. 30 | 2. Considere o primeiro elemento do sub-arranjo `B`. Denote este elemento `x`. 31 | 3. Procure no sub-arranjo `A` o ponto onde `x` deve ser inserido, da direita para a esquerda. 32 | 4. Desloque uma posição para a direita, todos os elementos no sub-arranjo `A` que estão à direita do ponto de inserção. 33 | 5. Insira o elemento `x` na posição de inserção encontrada no sub-arranjo `A`. 34 | 6. Se o sub-arranjo `B` não estiver vazio, volte ao Passo 2. 35 | 7. Retorne o sub-arranjo `A`, que contém os elementos da arranjo original ordenados. 36 | 37 | ## Qual é o desempenho do _Insertion Sort_? 38 | 39 | ### Pior Caso 40 | 41 | O pior caso para o algoritmo _Insertion Sort_ ocorre quando a lista de elementos está ordenada de forma inversa. Nessa situação, o algoritmo te um custo quadrático de comparações e de trocas, em função do número de elementos `n` a serem ordenados: 42 | 43 | - `O(n²)` comparações 44 | - `O(n²)` trocas 45 | 46 | ### Melhor Caso 47 | 48 | O melhor caso para o algoritmo _Insertion Sort_ ocorre quando a lista de elementos já está ordenada. Nessa situação, o algoritmo tem um custo linear de comparações e um custo constante de trocas, em função do número de elementos `n` a serem ordenados: 49 | 50 | - `O(n)` comparações 51 | - `O(1)` trocas 52 | 53 | ## Leitura Complementar 54 | 55 | - [Desenvolvendo Software | Insertion Sort](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/insertion-sort.html) 56 | -------------------------------------------------------------------------------- /sorting/insertion-sort/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = insertion-sort.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /sorting/insertion-sort/java/InsertionSort.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | import java.util.concurrent.ThreadLocalRandom; 4 | 5 | public class InsertionSort { 6 | // Sorts a List using Insertion Sort. 7 | public static > void sort(List list) { 8 | // Element 0 is in its place. Start from element 1: 9 | for (int i = 1; i < list.size(); i++) { 10 | int j = i; 11 | E element = list.get(i); 12 | 13 | // Keep swapping until the element's place is found 14 | while (j > 0 && element.compareTo(list.get(j - 1)) < 0) { 15 | list.set(j, list.get(j - 1)); 16 | j--; 17 | } 18 | 19 | // Assign the element to its place in the subarray 20 | list.set(j, element); 21 | } 22 | } 23 | 24 | private static List createRandomIntegerArrayList(int size, int lowerBound, int upperBound) { 25 | List list = new ArrayList<>(size); 26 | // Upper bound isn't usually inclusive, so add 1 27 | upperBound++; 28 | 29 | for (int i = 0; i < size; i++) 30 | list.add(ThreadLocalRandom.current().nextInt(lowerBound, upperBound)); 31 | 32 | return list; 33 | } 34 | 35 | private static > boolean isSorted(List list) { 36 | for (int i = 1; i < list.size(); i++) 37 | if (list.get(i).compareTo(list.get(i - 1)) < 0) return false; 38 | return true; 39 | } 40 | 41 | // Prints before and after, and times the test. 42 | private static void test(int size, int lowerBound, int upperBound) { 43 | int MICROSECS_PER_NANOSECS = 1000; 44 | List randomList = createRandomIntegerArrayList(size, lowerBound, upperBound); 45 | 46 | System.out.println("Random List:\n" + randomList); 47 | 48 | long start = System.nanoTime(); 49 | sort(randomList); 50 | long end = System.nanoTime(); 51 | 52 | assert isSorted(randomList); 53 | 54 | System.out.println("Sorted List:\n" + randomList); 55 | 56 | System.out.println("Time taken: " + (end - start) / MICROSECS_PER_NANOSECS + " us"); 57 | } 58 | 59 | // Reads args and runs test 60 | public static void main(String[] args) { 61 | int size = 10; 62 | int lowerBound = 0; 63 | int upperBound = 99; 64 | 65 | // Optional parameter: size of the list, range of values 66 | if (args.length > 0) { 67 | try { 68 | size = Integer.parseInt(args[0]); 69 | if (size < 1) 70 | throw new NumberFormatException(); 71 | } catch (NumberFormatException e) { 72 | System.out.println("Error parsing the argument: enter a positive integer, or no arguments for the default 10 value."); 73 | System.exit(1); 74 | } 75 | } 76 | 77 | if (args.length == 3) { 78 | try { 79 | lowerBound = Integer.parseInt(args[1]); 80 | upperBound = Integer.parseInt(args[2]); 81 | } catch (NumberFormatException e) { 82 | System.out.println("Error parsing the bounds: enter integers, or no arguments for the default 0 and 99 bounds."); 83 | System.exit(2); 84 | } 85 | } 86 | 87 | test(size, lowerBound, upperBound); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /sorting/insertion-sort/java/Makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | 4 | .SUFFIXES: .java .class 5 | 6 | .java.class: 7 | $(JC) $(JFLAGS) $*.java 8 | 9 | CLASSES = InsertionSort.java 10 | 11 | default: classes 12 | 13 | classes: $(CLASSES:.java=.class) 14 | 15 | clean: 16 | $(RM) *.class 17 | -------------------------------------------------------------------------------- /sorting/insertion-sort/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "insertion-sort" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /sorting/insertion-sort/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | use anyhow::Result; 4 | use rand::{ 5 | distributions::{uniform::SampleUniform, Uniform}, 6 | Rng, SeedableRng, 7 | }; 8 | use rand_chacha::ChaCha20Rng; 9 | use std::{env::args, time::Instant}; 10 | 11 | /// Sorts an array using Insertion Sort. 12 | fn insertion_sort(array: &mut [T]) { 13 | // Sorts the input array. 14 | for i in 1..array.len() { 15 | let mut j: usize = i; 16 | let tmp: T = array[i]; 17 | 18 | // Shift right elements while searching for insertion point. 19 | while (j > 0) && (tmp < array[j - 1]) { 20 | array[j] = array[j - 1]; 21 | j -= 1; 22 | } 23 | 24 | // Place the element in its final position. 25 | array[j] = tmp; 26 | } 27 | } 28 | 29 | /// Initializes an array. 30 | fn init_array(array: &mut Vec, rng: &mut ChaCha20Rng, range: Uniform) 31 | where 32 | T: SampleUniform, 33 | { 34 | for _ in 0..array.capacity() { 35 | array.push(rng.sample(&range)) 36 | } 37 | } 38 | 39 | /// Checks if an array is sorted. 40 | fn is_sorted(array: &[T]) -> bool { 41 | for i in 1..array.len() { 42 | if array[i] < array[i - 1] { 43 | return false; 44 | } 45 | } 46 | true 47 | } 48 | 49 | /// Tests Insertion Sort. 50 | fn test(length: usize, verbose: bool) { 51 | // Fix random number generator seed so that we have 52 | // a deterministic behavior across runs. 53 | let mut rng: ChaCha20Rng = ChaCha20Rng::seed_from_u64(0); 54 | let range: Uniform = Uniform::new(0, length); 55 | 56 | // Allocate and initialize array. 57 | let mut array: Vec = Vec::::with_capacity(length); 58 | init_array(&mut array, &mut rng, range); 59 | 60 | if verbose { 61 | println!("Input: {:?}", array); 62 | } 63 | 64 | let start: Instant = Instant::now(); 65 | insertion_sort(&mut array); 66 | let end: Instant = Instant::now(); 67 | 68 | // Report time. 69 | println!("Insertion Sort: {:.2?} us", (end - start).as_micros()); 70 | 71 | if verbose { 72 | println!("Output: {:?}", array); 73 | } 74 | 75 | // Check if array is sorted. 76 | assert_eq!(is_sorted(&array), true); 77 | } 78 | 79 | // Prints program usage. 80 | fn usage(args: &Vec) { 81 | println!("{} - Testing program for insertion sort.", args[0]); 82 | println!("Usage: {} [--verbose] ", args[0]); 83 | } 84 | 85 | fn main() -> Result<()> { 86 | let args: Vec = args().collect(); 87 | 88 | // Check for missing arguments. 89 | if (args.len() < 2) || (args.len() > 3) { 90 | usage(&args); 91 | anyhow::bail!("invalid number of arguments {:?}", args); 92 | } 93 | 94 | // Parse command line arguments. 95 | let (length, verbose): (usize, bool) = if args.len() == 2 { 96 | (args[1].parse()?, false) 97 | } else if (args.len() == 3) && (args[1] == "--verbose") { 98 | (args[2].parse()?, true) 99 | } else { 100 | anyhow::bail!("invalid argument"); 101 | }; 102 | 103 | test(length, verbose); 104 | 105 | Ok(()) 106 | } 107 | -------------------------------------------------------------------------------- /sorting/merge-sort/README.md: -------------------------------------------------------------------------------- 1 | # Merge Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /sorting/merge-sort/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Merge Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o _Merge Sort_?](#o-quê-é-o-merge-sort) 8 | - [Quando usar o _Merge Sort_?](#quando-usar-o-merge-sort) 9 | - [Quais são as características do _Merge Sort_?](#quais-são-as-características-do-merge-sort) 10 | - [Qual é o algoritmo do _Merge Sort_?](#qual-é-o-algoritmo-do-merge-sort) 11 | - [Qual é o desempenho do _Merge Sort_?](#qual-é-o-desempenho-do-merge-sort) 12 | - [Leitura Complementar](#leitura-complementar) 13 | 14 | ## O quê é o _Merge Sort_? 15 | 16 | O _Merge Sort_ (Ordenação por Mesclagem) é um algoritmo de ordenação por comparação criado por John von Neumann em 1945. O algoritmo funciona dividindo a coleção de elementos em duas sub-coleções, ordenando de forma recursiva cada sub-coleção e, em seguida, combinando as duas subcoleções. 17 | 18 | ## Quando usar o _Merge Sort_? 19 | 20 | - O _Merge Sort_ pode ser usado para ordenar coleções grandes 21 | - O _Merge Sort_ pode ser usado quando uma ordenação estável é necessária. 22 | 23 | ## Quais são as características do _Merge Sort_? 24 | 25 | - O _Merge Sort_ é um algoritmo de Divisão e Conquista. 26 | - O _Merge Sort_ é um algoritmo de ordenação por comparação. 27 | - O _Merge Sort_ é um algoritmo de ordenação estável. 28 | - O _Merge Sort_ pode ser usado para ordenar arranjos e listas. 29 | - O desempenho do merge sort não depende da disposição dos dados na coleção de entrada. 30 | 31 | ## Qual é o algoritmo do _Merge Sort_? 32 | 33 | 1. Verifique se a coleção possui apenas um elemento. Em caso afirmativo, retorne. 34 | 2. Divida a coleção em duas subcoleções. 35 | 3. Ordene recursivamente cada subcoleção. 36 | 4. Combine as duas subcoleções ordenadas em uma única. 37 | 5. Retorne a coleção ordenada. 38 | 39 | ## Qual é o desempenho do _Merge Sort_? 40 | 41 | O desempenho do algoritmo _Merge Sort_ não é impactado pela disposição dos dados no arranjo de entrada. Assim, o algoritmo apresenta tanto no pior caso quanto melhor caso um custo super-linear de comparações, em função do comprimento `n` do arranjo de entrada: 42 | 43 | - `O(n log₂ n)` comparações 44 | 45 | ## Leitura Complementar 46 | 47 | - [Desenvolvendo Software | Merge Sort](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/merge-sort.html) 48 | -------------------------------------------------------------------------------- /sorting/merge-sort/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = merge-sort.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /sorting/quicksort/README.md: -------------------------------------------------------------------------------- 1 | # Quicksort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | Quicksort is an efficient comparison sort algorithm devised by Tony Hoare in 8 | 1959. It features a Divide and Conquer design, and works by recursively 9 | partitioning and reordering the input array according to a _pivot_ element. 10 | 11 | Quicksort presents a slightly better performance than other comparison sort 12 | algorithms such as Merge Sort and Heapsort. 13 | 14 | Quicksort presents quadratic complexity when dealing with an array filled with 15 | duplicate keys. It can be modified by using a 3 way partitioning algorithm, 16 | making this case linear instead. 17 | 18 | ## Algorithm 19 | 20 | 1. If the array is shorter than two elements, stop recursing. 21 | 2. Select an element in the array and call it the _pivot_ element. 22 | 3. Partition and reorder the array into two sub-arrays, such that the elements 23 | that are less than the _pivot_ come before the division point and elements 24 | greater than the _pivot_ come after it. Elements that equal the _pivot_ can be 25 | placed on either of the partitions. 26 | 4. Recursively apply Steps 1 -- 3 in the the left and right sub-arrays. 27 | 5. When the recursion ends, the array is sorted. 28 | 29 | For dealing with duplicate keys, step 3 uses 3 sub-arrays instead, such that the 30 | elements that are less than the _pivot_ are placed in the first sub-array, the 31 | duplicate keys are palced in the second sub-array, and the elements greater than 32 | the _pivot_ are placed in the third sub-array. 33 | 34 | ## Performance 35 | 36 | - Best-Case: $O(n \log_2 n)$ comparisons 37 | - Worst-Case: $O(n^2)$ comparisons 38 | 39 | ## Further Reading 40 | 41 | - [Desenvolvendo Software](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/quicksort.html) (Portuguese) 42 | - [Wikipedia](https://en.wikipedia.org/wiki/Quicksort) 43 | -------------------------------------------------------------------------------- /sorting/quicksort/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = quicksort.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /sorting/quicksort/java/Makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | 4 | .SUFFIXES: .java .class 5 | 6 | .java.class: 7 | $(JC) $(JFLAGS) $*.java 8 | 9 | CLASSES = QuicksortDuplicateKeys.java 10 | 11 | default: classes 12 | 13 | classes: $(CLASSES:.java=.class) 14 | 15 | clean: 16 | $(RM) *.class -------------------------------------------------------------------------------- /sorting/quicksort/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "quicksort" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /sorting/selection-sort/README.md: -------------------------------------------------------------------------------- 1 | # Selection Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | Selection Sort is a sorting algorithm that works by selecting the smallest 8 | element in the array and placing it in the first position, then selecting the 9 | second smallest element in the array and placing it in the second position, and 10 | so on until the array is sorted. 11 | 12 | ## Algorithm 13 | 14 | 1. Partition the input array in two sub-arrays: a sub-array $A$ that is 15 | initially empty and will store all elements in their sorted order; and a 16 | sub-array $B$ with initially all elements from the input array. 17 | 2. Select the smallest element from the sub-array $B$ and place it in the last 18 | position of sub-array $A$. 19 | 3. If sub-array $B$ is not empty, go to Step 2. 20 | 4. Return sub-array $A$, which contains all elements from the original array 21 | sorted. 22 | 23 | ## Performance 24 | 25 | - Best-Case: $O(n^2)$ comparisons, $O(1)$ swaps. 26 | - Worst-Case: $O(n^2)$ comparisons, $O(n)$ swaps. 27 | 28 | ## Further Reading 29 | 30 | - [Desenvolvendo Software](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/selection-sort.html) (Portuguese) 31 | - [Wikipedia](https://en.wikipedia.org/wiki/Selection_sort) 32 | -------------------------------------------------------------------------------- /sorting/selection-sort/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Selection Sort 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o _Selection Sort_?](#o-quê-é-o-selection-sort) 8 | - [Quais são as características do _Selection Sort_?](#quais-são-as-características-do-selection-sort) 9 | - [Qual é o algoritmo do _Selection Sort_?](#qual-é-o-algoritmo-do-selection-sort) 10 | - [Qual é o desempenho do _Selection Sort_?](#qual-é-o-desempenho-do-selection-sort) 11 | - [Quando usar o _Selection Sort_?](#quando-usar-o-selection-sort) 12 | - [Leitura Complementar](#leitura-complementar) 13 | 14 | ## O quê é o _Selection Sort_? 15 | 16 | O _Selection Sort_ (Ordenação por Seleção) é um algoritmo de ordenação que funciona selecionando o menor elemento de um arranjo e colocando-o na primeira posição, depois selecionando o segundo menor elemento e colocando-o na segunda posição, e assim sucessivamente até que o arranjo esteja ordenado. 17 | 18 | ## Quais são as características do _Selection Sort_? 19 | 20 | - O _Selection Sort_ é um algoritmo iterativo. 21 | - O _Selection Sort_ é um algoritmo de ordenação por comparação. 22 | - O _Selection Sort_ não é um algoritmo de ordenação estável. 23 | - O desempenho do algoritmo _Selection Sort_ não é sensível aos dados de entrada. 24 | - O _Selection Sort_ não necessita de uma estrutura de dados auxiliar para funcionar. 25 | 26 | ## Qual é o algoritmo do _Selection Sort_? 27 | 28 | 1. Particione o arranjo de elementos a ser ordenado em dois sub-arranjos: (i) um sub-arranjo `A` inicialmente vazio que contém os elementos já ordenados, e (i) um sub-arranjo `B` com inicialmente todos os elementos do arranjo original. 29 | 2. Selecione o menor elemento da sub-arranjo `B` e coloque-o na última posição do sub-arranjo `A`. 30 | 3. Se o sub-arranjo `B` não estiver vazio, volte ao Passo 2. 31 | 4. Retorne o sub-arranjo `A`, que contém os elementos do arranjo original ordenados de forma ascendente. 32 | 33 | ## Qual é o desempenho do _Selection Sort_? 34 | 35 | ### Pior Caso 36 | 37 | O pior caso para o algoritmo _Selection Sort_ ocorre quando o arranjo de elementos já está ordenado de forma inversa. Nessa situação, o algoritmo tem um custo quadrático de comparações e um custo linear de trocas, em função do número de elementos a serem ordenados: 38 | 39 | - `O(n²)` comparações 40 | - `O(n)` trocas 41 | 42 | ### Melhor Caso 43 | 44 | O melhor caso para o algoritmo _Selection Sort_ ocorre quando o arranjo de elementos já está ordenado. Nessa situação, o algoritmo tem um custo quadrático de comparações e um custo constante de trocas, em função do número de elementos a serem ordenados: 45 | 46 | - `O(n²)` comparações 47 | - `O(1)` trocas 48 | 49 | ## Quando usar o _Selection Sort_? 50 | 51 | O _Selection Sort_ se destaca em relação aos outros algoritmos de ordenação em dois pontos: (i) por realizar um número mínimo de trocas, e (ii) não necessitar de uma estrutura de dados auxiliar para funcionar. 52 | 53 | Por esses motivos, o _Selection Sort_ é indicado para a ordenação de arranjos quando memória extra disponível para uso é escassa, ou então o custo para trocar-se elementos de posição no arranjo é elevado. 54 | 55 | ## Leitura Complementar 56 | 57 | - [Desenvolvendo Software | Selection Sort](http://desenvolvendosoftware.com.br/algoritmos/ordenacao/selection-sort.html) 58 | -------------------------------------------------------------------------------- /sorting/selection-sort/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = selection-sort.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /sorting/selection-sort/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "selection-sort" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /sorting/selection-sort/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | use anyhow::Result; 4 | use rand::{ 5 | distributions::{uniform::SampleUniform, Uniform}, 6 | Rng, SeedableRng, 7 | }; 8 | use rand_chacha::ChaCha20Rng; 9 | use std::{env::args, time::Instant}; 10 | 11 | /// Sorts an array using Selection Sort. 12 | fn selection_sort(array: &mut [T]) { 13 | // Sorts the input array. 14 | for i in 0..array.len() { 15 | let mut smallest: usize = i; 16 | 17 | // Find smallest element in the un-sorted sub-array. 18 | for j in i + 1..array.len() { 19 | // Found. 20 | if array[j] < array[smallest] { 21 | smallest = j; 22 | } 23 | } 24 | 25 | // Place smallest element in its final position. 26 | array.swap(i, smallest) 27 | } 28 | } 29 | 30 | /// Initializes an array. 31 | fn init_array(array: &mut Vec, rng: &mut ChaCha20Rng, range: Uniform) 32 | where 33 | T: SampleUniform, 34 | { 35 | for _ in 0..array.capacity() { 36 | array.push(rng.sample(&range)) 37 | } 38 | } 39 | 40 | /// Checks if an array is sorted. 41 | fn is_sorted(array: &[T]) -> bool { 42 | for i in 1..array.len() { 43 | if array[i - 1] > array[i] { 44 | return false; 45 | } 46 | } 47 | true 48 | } 49 | 50 | /// Tests Selection Sort. 51 | fn test(length: usize, verbose: bool) { 52 | // Fix random number generator seed so that we have 53 | // a deterministic behavior across runs. 54 | let mut rng: ChaCha20Rng = ChaCha20Rng::seed_from_u64(0); 55 | let range: Uniform = Uniform::new(0, length); 56 | 57 | // Allocate and initialize array. 58 | let mut array: Vec = Vec::::with_capacity(length); 59 | init_array(&mut array, &mut rng, range); 60 | 61 | if verbose { 62 | println!("Input: {:?}", array); 63 | } 64 | 65 | let start: Instant = Instant::now(); 66 | selection_sort(&mut array); 67 | let end: Instant = Instant::now(); 68 | 69 | // Report time. 70 | println!("Selection Sort: {:.2?} us", (end - start).as_micros()); 71 | 72 | // Check if array is sorted. 73 | assert_eq!(is_sorted(&array), true); 74 | 75 | if verbose { 76 | println!("Output: {:?}", array); 77 | } 78 | } 79 | 80 | // Prints program usage. 81 | fn usage(args: &Vec) { 82 | println!("{} - Testing program for selection sort.", args[0]); 83 | println!("Usage: {} [--verbose] ", args[0]); 84 | } 85 | 86 | fn main() -> Result<()> { 87 | let args: Vec = args().collect(); 88 | 89 | // Check for missing arguments. 90 | if (args.len() < 2) || (args.len() > 3) { 91 | usage(&args); 92 | anyhow::bail!("invalid number of arguments {:?}", args); 93 | } 94 | 95 | // Parse command line arguments. 96 | let (length, verbose): (usize, bool) = if args.len() == 2 { 97 | (args[1].parse()?, false) 98 | } else if (args.len() == 3) && (args[1] == "--verbose") { 99 | (args[2].parse()?, true) 100 | } else { 101 | anyhow::bail!("invalid argument"); 102 | }; 103 | 104 | test(length, verbose); 105 | 106 | Ok(()) 107 | } 108 | -------------------------------------------------------------------------------- /sorting/shell-sort/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = shell-sort.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= "1024" 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /sorting/shell-sort/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | [package] 4 | name = "shell-sort" 5 | version = "0.1.0" 6 | edition = "2021" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | rand = "0.8.5" 12 | rand_chacha = "0.3.1" 13 | anyhow = "1.0.68" 14 | -------------------------------------------------------------------------------- /string/lcs/README.md: -------------------------------------------------------------------------------- 1 | # LCS Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /string/lcs/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Algoritmo LCS 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o Algoritmo LCS?](#o-quê-é-o-algoritmo-lcs) 8 | - [Quais são as características do Algoritmo LCS?](#quais-são-as-características-do-algoritmo-lcs) 9 | - [Quais as aplicações do Algoritmo LCS?](#quais-as-aplicações-do-algoritmo-lcs) 10 | - [Qual é o Algoritmo LCS?](#qual-é-o-algoritmo-lcs) 11 | - [Qual o desempenho do Algoritmo LCS?](#qual-o-desempenho-do-algoritmo-lcs) 12 | 13 | ## O quê é o Algoritmo LCS? 14 | 15 | O Algoritmo LCS (_Longest Common Subsequence_) é um algoritmo que resolve o problema da Subsequência Comum Mais Longa ou Maior Subsequência Comum -- um problema clássico da ciência da computação que se resume a encontrar a maior subsequência comum entre duas sequências de elementos. Os elementos nesta subsequência não necessariamente devem ser contíguos nas sequências de entradas. 16 | 17 | ## Quais são as características do Algoritmo LCS? 18 | 19 | - O Algoritmo LCS é um algoritmo de programação dinâmica. 20 | - O Algoritmo LCS necessita de espaço de memória auxiliar para funcionar. 21 | - O desempenho do Algoritmo LCS depende somente do comprimento das sequências de entrada. 22 | 23 | ## Quais as aplicações do Algoritmo LCS? 24 | 25 | - **Comparação de Arquivos** -- O Algoritmo LCS é usado para comparar arquivos e identificar as diferenças entre eles. Isso é útil na sincronização de arquivos distribuídos ou na detecção de mudanças em arquivos ao longo do tempo. 26 | - **Detecção de Plágio** -- O Algoritmo LCS é usado para comparar documentos e identificar seções de texto semelhantes ou idênticas. Isso é útil na detecção de cópias não autorizadas ou no controle de qualidade de documentos. 27 | - **Processamento de String** -- O Algoritmo LCS é usado em problemas relacionados a processamento de string, como a identificação de palavras semelhantes ou a geração de sugestões de correção de palavras. 28 | - **Bioinformática** -- O Algoritmo LCS é usado na bioinformática para comparar sequências de DNA e proteínas e identificar regiões semelhantes ou idênticas. 29 | - **Sincronização de Arquivos** -- O Algoritmo LCS é usado para sincronizar arquivos entre diferentes dispositivos ou servidores, identificando as diferenças entre as versões e atualizando as informações de acordo. 30 | 31 | ## Qual é o Algoritmo LCS? 32 | 33 | 1. Inicialize uma tabela de `(n + 1)` linhas e `(m + 1)` colunas, onde `n` e `m` são os comprimentos das duas sequências de entrada. 34 | 2. Preencha a primeira linha e a primeira coluna com zeros. 35 | 3. Para cada elemento na primeira sequência, compare-o com cada elemento na segunda sequência. 36 | - Se os elementos forem iguais, armazene na tabela o valor da célula anterior diagonal mais `1`. 37 | - Caso contrário, armazene o máximo entre os valores das células acima e à esquerda. 38 | 4. O comprimento a subsequência comum mais longa será armazenado na célula na última linha e na última coluna da tabela. 39 | 5. Para construir a subsequência comum mais longa em si, comece na célula na última linha e na última coluna da tabela e siga os caminhos de maior valor de volta até a célula na primeira linha e na primeira coluna. 40 | 41 | ## Qual o desempenho do Algoritmo LCS? 42 | 43 | O desempenho do Algoritmo LCS é sensível somente ao comprimento `m` e `n` das sequências de entrada. Por esse motivo, no pior e melhor caso, o Algoritmo LCS possui um desempenho quadrático de comparações: 44 | 45 | - `O(mn)` comparações 46 | -------------------------------------------------------------------------------- /string/lcs/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = lcs.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= foobar 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /string/levenshtein/README.md: -------------------------------------------------------------------------------- 1 | # Levenshtein's Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /string/levenshtein/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Algoritmo de Levenshtein 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o Algoritmo de Levenshtein?](#o-quê-é-o-algoritmo-de-levenshtein) 8 | - [Quais são as características do Algoritmo de Levenshtein?](#quais-são-as-características-do-algoritmo-de-levenshtein) 9 | - [Quais as aplicações do Algoritmo de Levenshtein?](#quais-as-aplicações-do-algoritmo-de-levenshtein) 10 | - [Qual é o Algoritmo de Levenshtein?](#qual-é-o-algoritmo-de-levenshtein) 11 | - [Qual o desempenho do Algoritmo de Levenshtein?](#qual-o-desempenho-do-algoritmo-de-levenshtein) 12 | 13 | ## O quê é o Algoritmo de Levenshtein? 14 | 15 | O Algoritmo de Levenshtein é um algoritmo de programação dinâmica que calcula a distância de Levenshtein entre duas strings -- o número mínimo inserções, exclusões ou substituições necessárias para transformar uma string em outra. O Algoritmo de Levenshtein funciona preenchendo iterativamente uma tabela onde cada célula representa a distância de Levenshtein entre sub-strings das duas strings de entrada. O valor final na célula inferior direita da tabela é a distância de Levenshtein entre as duas strings completas. 16 | 17 | ## Quais são as características do Algoritmo de Levenshtein? 18 | 19 | - O Algoritmo de Levenshtein é um algoritmo de programação dinâmica. 20 | - O Algoritmo de Levenshtein necessita de espaço de memória auxiliar para funcionar. 21 | - O desempenho do Algoritmo de Levenshtein depende somente do comprimento das strings de entrada. 22 | 23 | ## Quais as aplicações do Algoritmo de Levenshtein? 24 | 25 | - **Verificação ortográfica** -- O Algoritmo de Levenshtein pode ser utilizado para sugerir correções para palavras escritas incorretamente. 26 | 27 | - **Análise de DNA** -- O Algoritmo de Levenshtein pode ser utilizado para comparar sequências de DNA e determinar sua similaridade. 28 | 29 | - **Recuperação de informação** -- O Algoritmo de Levenshtein pode ser utilizado para classificar ou recuperar informações relevantes baseadas em uma consulta de busca. 30 | 31 | - **Reconhecimento de fala** -- O Algoritmo de Levenshtein pode ser utilizado para comparar a fala reconhecida com a fala esperada e corrigir possíveis erros. 32 | 33 | - **Sistemas de sugestão** -- O Algoritmo de Levenshtein pode ser utilizado para sugerir palavras ou frases semelhantes a uma determinada string de entrada. 34 | 35 | ## Qual é o Algoritmo de Levenshtein? 36 | 37 | 1. Inicialize uma tabela de `(n+1)` linhas e `(m+1)` colunas, onde `n` é o comprimento da primeira string e `m` é o comprimento da segunda string. 38 | 2. Preencha a primeira linha e a primeira coluna com valores consecutivos, começando em zero. 39 | 3. Para cada caractere na primeira string, faça o seguinte: 40 | 1. Para cada caractere na segunda string, faça o seguinte: 41 | 2. Se os caracteres são iguais, armazene o valor diagonal na célula atual. 42 | 3. Caso contrário, armazene o mínimo dos valores adjacentes (esquerda, cima, diagonal) + 1 na célula atual. 43 | 4. O valor na célula inferior direita da matriz é a distância de Levenshtein entre as duas strings. 44 | 45 | ## Qual o desempenho do Algoritmo de Levenshtein? 46 | 47 | O desempenho do Algoritmo de Levenshtein é sensível somente ao comprimento `m` e `n` das sequências de entrada. Por esse motivo, no pior e melhor caso, o Algoritmo de Levenshtein possui um desempenho quadrático de comparações: 48 | 49 | - `O(mn)` comparações 50 | -------------------------------------------------------------------------------- /string/levenshtein/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = levenshtein.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= foobar 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /string/levenshtein/c/main.c: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // Returns the minimum of three values. 12 | #define MIN3(a, b, c) ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c))) 13 | 14 | // Computes the Levenshtein distance between two strings. 15 | static size_t levenshtein(const char *str1, const char *str2) 16 | { 17 | size_t len1 = strlen(str1); 18 | size_t len2 = strlen(str2); 19 | size_t table[len1 + 1][len2 + 1]; 20 | 21 | // Fill in dynamic programming table. 22 | for (size_t i = 0; i <= len1; i++) { 23 | for (size_t j = 0; j <= len2; j++) { 24 | // Delete all characters. 25 | if (i == 0) { 26 | table[0][j] = j; 27 | } 28 | // Insert all characters. 29 | else if (j == 0) { 30 | table[i][0] = i; 31 | } 32 | // Extend levenshtein distance. 33 | else { 34 | size_t cost = (str1[i - 1] == str2[j - 1]) ? 0 : 1; 35 | table[i][j] = MIN3(table[i - 1][j] + 1, table[i][j - 1] + 1, table[i - 1][j - 1] + cost); 36 | } 37 | } 38 | } 39 | 40 | return (table[len1][len2]); 41 | } 42 | 43 | // Tests Levenshtein. 44 | static void test(const char *str1, const char *str2, bool verbose) 45 | { 46 | size_t distance = 0; 47 | double tstart = 0.0; 48 | double tend = 0.0; 49 | const double MICROSECS = ((CLOCKS_PER_SEC / 1000000.0)); 50 | 51 | if (verbose) { 52 | printf("Compare: \'%s\', \'%s\'\n", str1, str2); 53 | } 54 | 55 | // Search string. 56 | tstart = clock(); 57 | distance = levenshtein(str1, str2); 58 | tend = clock(); 59 | 60 | // Report time. 61 | printf("levenstein: %2.lf us\n", (tend - tstart) / MICROSECS); 62 | 63 | if (verbose) { 64 | printf("Output: %d\n", distance); 65 | } 66 | } 67 | 68 | // Prints program usage and exits. 69 | static void usage(char *const argv[]) 70 | { 71 | printf("%s - Testing program for levenshtein.\n", argv[0]); 72 | printf("Usage: %s [--verbose] \n", argv[0]); 73 | exit(EXIT_FAILURE); 74 | } 75 | 76 | // Drives the test function. 77 | int main(int argc, char *const argv[]) 78 | { 79 | const char *str1 = NULL; 80 | const char *str2 = NULL; 81 | bool verbose = false; 82 | 83 | // Check for missing arguments. 84 | if ((argc < 3) || (argc > 4)) { 85 | printf("Error: invalid number of arguments.\n"); 86 | usage(argv); 87 | } 88 | 89 | // Parse command line arguments. 90 | if (argc == 3) { 91 | str1 = argv[1]; 92 | str2 = argv[2]; 93 | } else if ((argc == 4) && (!strcmp(argv[1], "--verbose"))) { 94 | str1 = argv[2]; 95 | str2 = argv[3]; 96 | verbose = true; 97 | } else { 98 | printf("Error: invalid arguments.\n"); 99 | usage(argv); 100 | } 101 | 102 | // Run it! 103 | test(str1, str2, verbose); 104 | 105 | return (EXIT_SUCCESS); 106 | } 107 | -------------------------------------------------------------------------------- /string/search/bmh/README.md: -------------------------------------------------------------------------------- 1 | # BMH Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /string/search/bmh/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = bmh.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= foobar 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /string/search/brute-force/README.md: -------------------------------------------------------------------------------- 1 | # Brute-Force Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /string/search/brute-force/README.pt-br.md: -------------------------------------------------------------------------------- 1 | # Algoritmo Força-Bruta 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Leia isso em outros idiomas: [English](README.md), [Português](README.pt-br.md)_ 6 | 7 | - [O quê é o Algoritmo Força-Bruta?](#o-quê-é-o-algoritmo-força-bruta) 8 | - [Quais são as características do Algoritmo Força-Bruta?](#quais-são-as-características-do-algoritmo-força-bruta) 9 | - [Qual é o Algoritmo Força-Bruta?](#qual-é-o-algoritmo-força-bruta) 10 | - [Qual o desempenho do Algoritmo Força-Bruta?](#qual-o-desempenho-do-algoritmo-força-bruta) 11 | 12 | ## O quê é o Algoritmo Força-Bruta? 13 | 14 | O Algoritmo Força-Bruta consiste em uma forma simples, ingênua e ineficiente para realizar o casamento de padrões. O algoritmo funciona deslizando uma janela de comparação no texto de entrada símbolo a símbolo e comparando se cada trecho de texto considerado corresponde ao padrão buscado. 15 | 16 | ## Quais são as características do Algoritmo Força-Bruta? 17 | 18 | - O Algoritmo de Força-Bruta faz uma busca exata de um padrão em um texto de entrada. 19 | - O Algoritmo de Força-Bruta funciona deslizando uma janela de comparação pelo texto de entrada. 20 | - O Algoritmo de Força-Bruta não necessita de espaço auxiliar de memória para funcionar. 21 | - O Algoritmo de Força-Bruta é ineficiente. 22 | - O desempenho do Algoritmo Força-Bruta não depende do padrão buscado. 23 | 24 | ## Qual é o Algoritmo Força-Bruta? 25 | 26 | 1. Posicione a janela deslizante de comparação no primeiro símbolo do texto de entrada e inicie a busca: 27 | 1. Compare o trecho de texto na janela deslizante com o padrão buscado, começado pelo último símbolo do padrão em direção ao primeiro. 28 | 2. Caso algum símbolo seja diferente, avance para o próximo símbolo no texto de entrada. 29 | 3. Caso o trecho de texto corresponda ao padrão buscado, adicione esse trecho ao conjunto de trechos encontrados e interrompa a busca. 30 | 2. Retorne o conjunto de trechos que correspondem ao padrão buscado. Se nenhuma correspondência foi encontrada, esse conjunto está vazio. 31 | 32 | ## Qual o desempenho do Algoritmo Força-Bruta? 33 | 34 | ### Melhor Caso 35 | 36 | O melhor caso para o Algoritmo Força-Bruta para o casamento de padrões ocorre quando o padrão buscado está nas posições iniciais do texto de entrada. Nesse cenário, o desempenho do algoritmo é linear no número de comparações, em função do comprimento `n` do padrão buscado: 37 | 38 | - `O(n)` comparações 39 | 40 | ### Pior Caso 41 | 42 | O pior caso para o Algoritmo Força-Bruta para o casamento de padrões ocorre quando o padrão buscado não está no texto de entrada. Nesse cenário, o desempenho do algoritmo é quadrático no número de comparações, em função do comprimento `m` do texto de entrada e do comprimento `n` do padrão buscado: 43 | 44 | - `O(mn)` comparações 45 | -------------------------------------------------------------------------------- /string/search/brute-force/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = brute-force.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= foobar 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /string/search/kmp/README.md: -------------------------------------------------------------------------------- 1 | # KMP Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /string/search/kmp/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = kmp.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= foobar 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | -------------------------------------------------------------------------------- /string/search/rabin-karp/README.md: -------------------------------------------------------------------------------- 1 | # Rabin-Karp Algorithm 2 | 3 | [![en](https://img.shields.io/badge/lang-en-red.svg)](./README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) 4 | 5 | _Read this in other languages: [English](README.md), [Português](README.pt-br.md)_ 6 | -------------------------------------------------------------------------------- /string/search/rabin-karp/c/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Pedro Henrique Penna 2 | 3 | # Directories 4 | BINDIR = $(CURDIR) 5 | 6 | # Source Files 7 | SRC = $(wildcard *.c) 8 | 9 | # Name of Executable File 10 | EXEC = rabin-karp.elf 11 | 12 | # Default Run Arguments 13 | ARGS ?= foobar 14 | 15 | #=============================================================================== 16 | # Compiler Configuration 17 | #=============================================================================== 18 | 19 | # Compiler 20 | CC = gcc 21 | 22 | # Compiler Flags 23 | CFLAGS = -Og -g 24 | CFLAGS += -std=c11 -fno-builtin -pedantic 25 | CFLAGS += -Wall -Wextra -Werror -Wa,--warn 26 | CFLAGS += -Winit-self -Wswitch-default -Wfloat-equal 27 | CFLAGS += -Wundef -Wshadow -Wuninitialized -Wlogical-op 28 | CFLAGS += -Wredundant-decls 29 | CFLAGS += -Wno-missing-profile 30 | 31 | #=============================================================================== 32 | # Build Rules 33 | #=============================================================================== 34 | 35 | # Builds everything. 36 | all: build 37 | 38 | # Runs. 39 | run: $(EXEC) 40 | @$(BINDIR)/$(EXEC) $(ARGS) 41 | 42 | # Builds all artifacts. 43 | build: $(EXEC) 44 | 45 | # Cleans up all build artifacts. 46 | clean: 47 | @rm -f $(BINDIR)/*.elf 48 | 49 | # Builds a single executable file. 50 | %.elf: $(SRC) 51 | @$(CC) $(CFLAGS) $< -o $(BINDIR)/$@ 52 | --------------------------------------------------------------------------------