From d0e8d66e19c92ce30079ecfbba33c51d86fc066d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Wo=CC=81jcik?= Date: Sat, 2 Oct 2021 19:17:45 +0200 Subject: [PATCH 01/11] Add alghorithms for conversion from binary to decimal and decimal to binary --- algorithms/conversion/binary-to-decimal.swift | 23 +++++++++++++++++++ algorithms/conversion/decimal-to-binary.swift | 12 ++++++++++ 2 files changed, 35 insertions(+) create mode 100644 algorithms/conversion/binary-to-decimal.swift create mode 100644 algorithms/conversion/decimal-to-binary.swift diff --git a/algorithms/conversion/binary-to-decimal.swift b/algorithms/conversion/binary-to-decimal.swift new file mode 100644 index 0000000..c5cf3da --- /dev/null +++ b/algorithms/conversion/binary-to-decimal.swift @@ -0,0 +1,23 @@ +import Foundation + +/// This function accepts a binary number as String and converts it to decimal as Int. +/// If it's not valid binary number (a.k.a not made only from digits), it returns nil. +public func convertBinaryToDecimal(binary: String) -> Int? { + if let _ = Int(binary) { + var decimal = 0 + + let digits = binary.map { Int(String($0))! }.reversed() + print(digits) + var power = 1 + + for digit in digits { + decimal += digit * power + + power *= 2 + } + + return decimal + } + + return nil +} \ No newline at end of file diff --git a/algorithms/conversion/decimal-to-binary.swift b/algorithms/conversion/decimal-to-binary.swift new file mode 100644 index 0000000..2969fdd --- /dev/null +++ b/algorithms/conversion/decimal-to-binary.swift @@ -0,0 +1,12 @@ +/// This function accepts a non-negative number and returns its binary form as String. +public func convertDecimalToBinary(decimal: Int) -> String { + var binary = "" + var decimal = decimal + + while decimal != 0 { + binary.insert(decimal % 2 == 0 ? "0" : "1", at: binary.startIndex) + decimal /= 2 + } + + return binary +} \ No newline at end of file From da6daecc070b329c8b5e95a3e1e69511b9117e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Wo=CC=81jcik?= Date: Sat, 2 Oct 2021 19:22:12 +0200 Subject: [PATCH 02/11] Update DIRECTORY.md --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index e1bce5e..7873d7f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -1,6 +1,9 @@ # List of all files ## Algorithms + * conversion + * [Binary to decimal](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/binary-to-decimal.swift) + * [Decimal to binary](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/decimal-to-binary.swift) * Ai * Minimax * Sources From 7590755cc2b7094566021cdeaab1861d489239a4 Mon Sep 17 00:00:00 2001 From: Maria Fernanda Azolin Date: Wed, 13 Oct 2021 09:45:13 -0300 Subject: [PATCH 03/11] adds cocktail sort algorithm --- DIRECTORY.md | 1 + sorts/CocktailSort.swift | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 sorts/CocktailSort.swift diff --git a/DIRECTORY.md b/DIRECTORY.md index e1bce5e..c7fdfa6 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -58,6 +58,7 @@ ## Sorts * [Bubblesort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/BubbleSort.swift) + * [Cocktailsort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/CocktailSort.swift) * [Insertionsort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/InsertionSort.swift) * [Mergesort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/MergeSort.swift) * [Quicksort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/QuickSort.swift) diff --git a/sorts/CocktailSort.swift b/sorts/CocktailSort.swift new file mode 100644 index 0000000..d9b1110 --- /dev/null +++ b/sorts/CocktailSort.swift @@ -0,0 +1,49 @@ + +/* + Cocktail Sort (or Cocktail shaker sort) is a variation of Bubble sort. + The Bubble sort algorithm always traverses elements from left and moves the largest element + to its correct position in first iteration and second largest in second iteration and so on. + Cocktail Sort traverses through a given array in both directions alternatively. +*/ + +import Foundation + +func cocktailSort(_ a: [T]) -> [T] { + var list = a + var swapped = true + var start = 0 + var end = list.count - 1 + + while (swapped) { + swapped = false + + for i in start.. list[i + 1]) { + list.swapAt(i, i+1) + swapped = true + } + } + + if (!swapped) { + break + } + swapped = false + end -= 1 + + for index in stride(from: end-1, through: start, by: -1) { + if (list[index] > list[index + 1]) { + list.swapAt(index, index+1) + swapped = true + } + } + start += 1 + } + + return list +} + +// The code below can be used for testing + +//var numbers = [2, -4, 4, 6, 1, 12, 9, 0] +//numbers = cocktailSort(numbers) +//print(numbers) From 3affd0bc667d46178a606707f3dd705cf375be16 Mon Sep 17 00:00:00 2001 From: Maria Fernanda Azolin Date: Wed, 13 Oct 2021 11:12:26 -0300 Subject: [PATCH 04/11] adds pancake sort algorithm --- DIRECTORY.md | 1 + sorts/PancakeSort.swift | 51 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 sorts/PancakeSort.swift diff --git a/DIRECTORY.md b/DIRECTORY.md index c7fdfa6..f78dc04 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -61,6 +61,7 @@ * [Cocktailsort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/CocktailSort.swift) * [Insertionsort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/InsertionSort.swift) * [Mergesort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/MergeSort.swift) + * [Pancakesort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/PancakeSort.swift) * [Quicksort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/QuickSort.swift) * [Selectionsort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/SelectionSort.swift) diff --git a/sorts/PancakeSort.swift b/sorts/PancakeSort.swift new file mode 100644 index 0000000..3a016fb --- /dev/null +++ b/sorts/PancakeSort.swift @@ -0,0 +1,51 @@ + +/* + Pancake sorting is the mathematical problem of sorting a disordered stack + of pancakes in order of size when a spatula can be inserted at any + point in the stack and used to flip all pancakes above it. + */ + +import Foundation + +func flip(array: [Int], key: Int) -> [Int] { + var flippedArray = array + var pos = key + var start = 0 + var aux = 0 + + while (start < pos) { + aux = flippedArray[start] + flippedArray[start] = flippedArray[pos] + flippedArray[pos] = aux + + start += 1 + pos -= 1 + } + + return flippedArray +} + +func pancakeSort(_ array: [Int]) -> [Int] { + var list = array + var currentSize = list.count + for _ in (1 ..< currentSize).reversed() { + + let listToSearch = list[0...currentSize-1] + let max = listToSearch.max() ?? 0 + let indexOfMax = listToSearch.firstIndex(of: max) ?? 0 + + if indexOfMax != currentSize - 1 { + list = flip(array: list, key: indexOfMax) + list = flip(array: list, key: currentSize - 1) + } + + currentSize -= 1 + } + + return list +} + +// The code below can be used for testing +//var numbers = [2, 4, 6, 12, 3, -2, 9, 14, 22, 0, 18] +//numbers = pancakeSort(numbers) +//print(numbers) From ffa65992d07befb9c4dfc8efdf722f6a7366ceba Mon Sep 17 00:00:00 2001 From: Samuel Kosasih Date: Wed, 10 May 2023 15:54:15 -0400 Subject: [PATCH 05/11] Implemented a Doubly Linked List structure --- .../doubly_linked_list/DoublyLinkedList.swift | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 data_structures/doubly_linked_list/DoublyLinkedList.swift diff --git a/data_structures/doubly_linked_list/DoublyLinkedList.swift b/data_structures/doubly_linked_list/DoublyLinkedList.swift new file mode 100644 index 0000000..ca9f614 --- /dev/null +++ b/data_structures/doubly_linked_list/DoublyLinkedList.swift @@ -0,0 +1,194 @@ +import Foundation + +public class Node { + public var value: Value? + public var next: Node? + public var prev: Node? + + public init(value: Value? = nil, next: Node? = nil, prev: Node? = nil) { + self.value = value + self.next = next + self.prev = prev + } +} + +extension Node: CustomStringConvertible { + public var description: String { + guard let next: Node = self.next else { + return "\(String(describing: value))" + } + return "\(String(describing: value)) <-> \(String(describing: next)) " + } +} + +public struct DoublyLinkedList { + + public var head: Node? + public var tail: Node? + public var count: Int = 0 + + public var isEmpty: Bool { + return head == nil + } + + public mutating func push(_ value: Value) { + let new: Node = Node(value: value, next: head) + if head != nil { head!.prev = new } + head = new + if tail == nil { tail = head } + count += 1 + } + + public mutating func append(_ value: Value) { + guard !isEmpty else { + push(value) + return + } + tail!.next = Node(value: value, prev: tail) + tail = tail!.next + count += 1 + } + + @discardableResult + public mutating func insert(_ value: Value, + after node: Node) -> Node { + guard tail !== node else { + append(value) + return tail! + } + var new: Node = Node(value: value, next: node.next, prev: node) + node.next?.prev = new + node.next = new + count += 1 + return node.next! + } + + @discardableResult + public mutating func insert(_ value: Value, + before node: Node) -> Node { + guard head !== node else { + push(value) + return head! + } + var new: Node = Node(value: value, next: node, prev: node.prev) + node.prev?.next = new + node.prev = new + count += 1 + return node.prev! + } + + public func node(at index: Int) -> Node? { + guard index > -1 || index < count else { return nil } + + let startFromTail: Bool = index > count / 2 + var currentNode: Node? = startFromTail ? tail : head + var currentIndex: Int = startFromTail ? count - 1 : 0 + var change: Int = startFromTail ? -1 : 1 + + while currentNode != nil { + if currentIndex == index { break } + currentNode = startFromTail ? currentNode!.prev : currentNode!.next + currentIndex += change + } + + return currentNode + } + + @discardableResult + public mutating func pop() -> Value? { + defer { + head = head?.next + count -= 1 + if isEmpty { + tail = nil + } else { + head!.prev = nil + } + } + return head?.value + } + + @discardableResult + public mutating func removeLast() -> Value? { + defer { + tail = tail?.prev + count -= 1 + if isEmpty { + head = nil + } else { + tail!.next = nil + } + } + return tail?.value + } + + @discardableResult + public mutating func remove(after node: Node) -> Value? { + defer { + if node.next != nil { + count -= 1 + } + if node.next === tail { + tail = node + } + if let next2node: Node = node.next?.next { + next2node.prev = node + } + node.next = node.next?.next + } + return node.next?.value + } + + @discardableResult + public mutating func remove(before node: Node) -> Value? { + defer { + if node.prev != nil { + count -= 1 + } + if node.prev === head { + head = node + } + if let prev2node: Node = node.prev?.prev { + prev2node.next = node + } + node.prev = node.prev?.prev + } + return node.prev?.value + } +} + +extension DoublyLinkedList: CustomStringConvertible { + public var description: String { + guard let head: Node = self.head else { + return "Empty list" + } + return String(describing: head) + } +} + +// Here are testing scenarios to run in a Swift playground + +/* +var list = DoublyLinkedList() + +list.push(4) +list.push(2) +list.push(1) + +list.append(6) + +var n = list.node(at: 2) + +list.insert(5, after: n!) +list.insert(3, before: n!) + +print(list) + +print(list.pop()!) +print(list.removeLast()!) + +print(list.remove(after: n!)!) +print(list.remove(before: n!)!) + +print(list.count) +*/ From c459742f98eeb33a3c547267c60aa52f00977e8a Mon Sep 17 00:00:00 2001 From: abhishek2513 Date: Tue, 6 Jun 2023 20:46:45 +0530 Subject: [PATCH 06/11] added BFS and DFS traversals --- graph/BFS/BFS.swift | 75 +++++++++++++++++++++++++++++++++++++++++++++ graph/DFS/DFS.swift | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 graph/BFS/BFS.swift create mode 100644 graph/DFS/DFS.swift diff --git a/graph/BFS/BFS.swift b/graph/BFS/BFS.swift new file mode 100644 index 0000000..24d99ce --- /dev/null +++ b/graph/BFS/BFS.swift @@ -0,0 +1,75 @@ +// MARK: - Basic requirement +struct Edge { + let from: Int + let to: Int +} + +public class Node { + var val: Int + var neighbors: [Int] + public init(_ val: Int) { + self.val = val + self.neighbors = [] + } +} + +// MARK: - BFS implementation +func testBFS(edges: [Edge]) { + + var graph = [Int: Node]() + for edge in edges { + graph[edge.from] = Node(edge.from) + graph[edge.to] = Node(edge.to) + } + for edge in edges { + graph[edge.from]?.neighbors.append(edge.to) + graph[edge.to]?.neighbors.append(edge.from) + } + var visited: [Bool] = Array(repeating: false, count: graph.count + 1) + var nodesOfCurrentLevel: [Int] = [] + + for node in 1...graph.count { + if visited[node] == false { + nodesOfCurrentLevel.append(node) + while(nodesOfCurrentLevel.isEmpty == false) { + var nodesOfNextLevel: [Int] = [] + let sizeOfQueue = nodesOfCurrentLevel.count + for index in 0.. Date: Tue, 5 Mar 2024 00:15:33 +0300 Subject: [PATCH 07/11] Add string palindrome algorithm --- .../palindrome/palindrome_indices.swift | 32 ++++++++++++++ .../palindrome/palindrome_recursion.swift | 44 +++++++++++++++++++ .../palindrome/palindrome_reversed.swift | 13 ++++++ 3 files changed, 89 insertions(+) create mode 100644 algorithms/palindrome/palindrome_indices.swift create mode 100644 algorithms/palindrome/palindrome_recursion.swift create mode 100644 algorithms/palindrome/palindrome_reversed.swift diff --git a/algorithms/palindrome/palindrome_indices.swift b/algorithms/palindrome/palindrome_indices.swift new file mode 100644 index 0000000..06dd880 --- /dev/null +++ b/algorithms/palindrome/palindrome_indices.swift @@ -0,0 +1,32 @@ +// A palindrome is a string that reads the same forwards and backwards. +// +// Examples: "level", "radar", "madam", "A man, a plan, a canal: Panama". + +extension String { + + /// Iteratively comparing characters from the beginning and end of the string. Only include letters and numbers. + /// - Complexity: O(n), without allocating new space. + func isPalindrome() -> Bool { + var leftIndex = startIndex + var rightIndex = index(before: endIndex) + + while leftIndex < rightIndex { + guard self[leftIndex].isLetter || self[leftIndex].isNumber else { + leftIndex = index(after: leftIndex) + continue + } + guard self[rightIndex].isLetter || self[rightIndex].isNumber else { + rightIndex = index(before: rightIndex) + continue + } + guard self[leftIndex].lowercased() == self[rightIndex].lowercased() else { + return false + } + + leftIndex = index(after: leftIndex) + rightIndex = index(before: rightIndex) + } + + return true + } +} diff --git a/algorithms/palindrome/palindrome_recursion.swift b/algorithms/palindrome/palindrome_recursion.swift new file mode 100644 index 0000000..1eb8b46 --- /dev/null +++ b/algorithms/palindrome/palindrome_recursion.swift @@ -0,0 +1,44 @@ +// A palindrome is a string that reads the same forwards and backwards. +// +// Examples: "level", "radar", "madam", "A man, a plan, a canal: Panama". + +extension String { + + /// Recursively comparing characters from the beginning and end of the string. Only include letters and numbers. + /// - Complexity: O(n), without allocating new space. + func isPalindrome() -> Bool { + isPalindromeRecursion( + leftIndex: startIndex, + rightIndex: index(before: endIndex) + ) + } + + private func isPalindromeRecursion( + leftIndex: String.Index, + rightIndex: String.Index + ) -> Bool { + guard leftIndex < rightIndex else { + return true + } + guard self[leftIndex].isLetter || self[leftIndex].isNumber else { + return isPalindromeRecursion( + leftIndex: index(after: leftIndex), + rightIndex: rightIndex + ) + } + guard self[rightIndex].isLetter || self[rightIndex].isNumber else { + return isPalindromeRecursion( + leftIndex: leftIndex, + rightIndex: index(before: rightIndex) + ) + } + guard self[leftIndex].lowercased() == self[rightIndex].lowercased() else { + return false + } + + return isPalindromeRecursion( + leftIndex: index(after: leftIndex), + rightIndex: index(before: rightIndex) + ) + } +} diff --git a/algorithms/palindrome/palindrome_reversed.swift b/algorithms/palindrome/palindrome_reversed.swift new file mode 100644 index 0000000..0c5659c --- /dev/null +++ b/algorithms/palindrome/palindrome_reversed.swift @@ -0,0 +1,13 @@ +// A palindrome is a string that reads the same forwards and backwards. +// +// Examples: "level", "radar", "madam", "A man, a plan, a canal: Panama". + +extension String { + + /// Using the `reverse()` method to reverse the string and comparing it with the original. Only include letters and numbers. + /// - Complexity: O(n), with allocating O(n) space. + func isPalindrome() -> Bool { + let input = lowercased().filter { $0.isLetter || $0.isNumber } + return input == String(input.reversed()) + } +} From 533e81946d566df26b228824c530d4ea8bea9d13 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 11 Mar 2024 08:56:31 +0000 Subject: [PATCH 08/11] updating DIRECTORY.md --- DIRECTORY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index e1bce5e..2c0e562 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -46,6 +46,10 @@ * [Union Find](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/union_find/union_find.swift) ## Graph + * Bfs + * [Bfs](https://github.com/TheAlgorithms/Swift/blob/master/graph/BFS/BFS.swift) + * Dfs + * [Dfs](https://github.com/TheAlgorithms/Swift/blob/master/graph/DFS/DFS.swift) * Spanning Tree * [Kruskal](https://github.com/TheAlgorithms/Swift/blob/master/graph/spanning_tree/kruskal.swift) From 00ac7861d0ae06667736b16d95bf0163c86a0520 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 11 Mar 2024 08:57:04 +0000 Subject: [PATCH 09/11] updating DIRECTORY.md --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 2c0e562..e469005 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -34,6 +34,8 @@ * [Shunting Yard](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/parsing/shunting_yard/shunting_yard.swift) ## Data Structures + * Doubly Linked List + * [Doublylinkedlist](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/doubly_linked_list/DoublyLinkedList.swift) * Heap * [Heap](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/heap/heap.swift) * Linked List From 99e978b3cae70bf14921dfaab66784ad9d2255df Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 13 May 2024 13:50:06 +0000 Subject: [PATCH 10/11] updating DIRECTORY.md --- DIRECTORY.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 649ddcf..cc70d14 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -1,9 +1,6 @@ # List of all files ## Algorithms - * conversion - * [Binary to decimal](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/binary-to-decimal.swift) - * [Decimal to binary](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/decimal-to-binary.swift) * Ai * Minimax * Sources @@ -32,6 +29,9 @@ * [Boardtests](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Tests/Tests/BoardTests.swift) * [Minimaxtests](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Tests/Tests/MinimaxTests.swift) * [Playertests](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Tests/Tests/PlayerTests.swift) + * Conversion + * [Binary-To-Decimal](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/binary-to-decimal.swift) + * [Decimal-To-Binary](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/decimal-to-binary.swift) * Parsing * Shunting Yard * [Shunting Yard](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/parsing/shunting_yard/shunting_yard.swift) From c864c82753a32f70bae1de01ba9b3e97a4ac36e2 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 14 May 2024 12:30:54 +0000 Subject: [PATCH 11/11] updating DIRECTORY.md --- DIRECTORY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index cc70d14..0044fdd 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -32,6 +32,10 @@ * Conversion * [Binary-To-Decimal](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/binary-to-decimal.swift) * [Decimal-To-Binary](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/decimal-to-binary.swift) + * Palindrome + * [Palindrome Indices](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/palindrome/palindrome_indices.swift) + * [Palindrome Recursion](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/palindrome/palindrome_recursion.swift) + * [Palindrome Reversed](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/palindrome/palindrome_reversed.swift) * Parsing * Shunting Yard * [Shunting Yard](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/parsing/shunting_yard/shunting_yard.swift)