Fix DataStructures links

This commit is contained in:
freak4pc 2019-01-26 17:11:07 +02:00 committed by Krunoslav Zaher
parent 937fef1991
commit 120b3baa3d
4 changed files with 4 additions and 470 deletions

View File

@ -1,181 +0,0 @@
//
// Bag.swift
// Platform
//
// Created by Krunoslav Zaher on 2/28/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Swift
let arrayDictionaryMaxSize = 30
struct BagKey {
/**
Unique identifier for object added to `Bag`.
It's underlying type is UInt64. If we assume there in an idealized CPU that works at 4GHz,
it would take ~150 years of continuous running time for it to overflow.
*/
fileprivate let rawValue: UInt64
}
/**
Data structure that represents a bag of elements typed `T`.
Single element can be stored multiple times.
Time and space complexity of insertion and deletion is O(n).
It is suitable for storing small number of elements.
*/
struct Bag<T>: CustomDebugStringConvertible {
/// Type of identifier for inserted elements.
typealias KeyType = BagKey
typealias Entry = (key: BagKey, value: T)
fileprivate var _nextKey: BagKey = BagKey(rawValue: 0)
// data
// first fill inline variables
var _key0: BagKey?
var _value0: T?
// then fill "array dictionary"
var _pairs = ContiguousArray<Entry>()
// last is sparse dictionary
var _dictionary: [BagKey: T]?
var _onlyFastPath = true
/// Creates new empty `Bag`.
init() {
}
/**
Inserts `value` into bag.
- parameter element: Element to insert.
- returns: Key that can be used to remove element from bag.
*/
mutating func insert(_ element: T) -> BagKey {
let key = self._nextKey
self._nextKey = BagKey(rawValue: self._nextKey.rawValue &+ 1)
if self._key0 == nil {
self._key0 = key
self._value0 = element
return key
}
self._onlyFastPath = false
if self._dictionary != nil {
self._dictionary![key] = element
return key
}
if self._pairs.count < arrayDictionaryMaxSize {
self._pairs.append((key: key, value: element))
return key
}
self._dictionary = [key: element]
return key
}
/// - returns: Number of elements in bag.
var count: Int {
let dictionaryCount: Int = self._dictionary?.count ?? 0
return (self._value0 != nil ? 1 : 0) + self._pairs.count + dictionaryCount
}
/// Removes all elements from bag and clears capacity.
mutating func removeAll() {
self._key0 = nil
self._value0 = nil
self._pairs.removeAll(keepingCapacity: false)
self._dictionary?.removeAll(keepingCapacity: false)
}
/**
Removes element with a specific `key` from bag.
- parameter key: Key that identifies element to remove from bag.
- returns: Element that bag contained, or nil in case element was already removed.
*/
mutating func removeKey(_ key: BagKey) -> T? {
if self._key0 == key {
self._key0 = nil
let value = self._value0!
self._value0 = nil
return value
}
if let existingObject = self._dictionary?.removeValue(forKey: key) {
return existingObject
}
for i in 0 ..< self._pairs.count where self._pairs[i].key == key {
let value = self._pairs[i].value
self._pairs.remove(at: i)
return value
}
return nil
}
}
extension Bag {
/// A textual representation of `self`, suitable for debugging.
var debugDescription: String {
return "\(self.count) elements in Bag"
}
}
extension Bag {
/// Enumerates elements inside the bag.
///
/// - parameter action: Enumeration closure.
func forEach(_ action: (T) -> Void) {
if self._onlyFastPath {
if let value0 = self._value0 {
action(value0)
}
return
}
let value0 = self._value0
let dictionary = self._dictionary
if let value0 = value0 {
action(value0)
}
for i in 0 ..< self._pairs.count {
action(self._pairs[i].value)
}
if dictionary?.count ?? 0 > 0 {
for element in dictionary!.values {
action(element)
}
}
}
}
extension BagKey: Hashable {
var hashValue: Int {
return self.rawValue.hashValue
}
}
func ==(lhs: BagKey, rhs: BagKey) -> Bool {
return lhs.rawValue == rhs.rawValue
}

View File

@ -0,0 +1 @@
../../../Platform/DataStructures/Bag.swift

View File

@ -1,26 +0,0 @@
//
// InfiniteSequence.swift
// Platform
//
// Created by Krunoslav Zaher on 6/13/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
/// Sequence that repeats `repeatedValue` infinite number of times.
struct InfiniteSequence<E>: Sequence {
typealias Element = E
typealias Iterator = AnyIterator<E>
private let _repeatedValue: E
init(repeatedValue: E) {
self._repeatedValue = repeatedValue
}
func makeIterator() -> Iterator {
let repeatedValue = self._repeatedValue
return AnyIterator {
return repeatedValue
}
}
}

View File

@ -0,0 +1 @@
../../../Platform/DataStructures/InfiniteSequence.swift

View File

@ -1,111 +0,0 @@
//
// PriorityQueue.swift
// Platform
//
// Created by Krunoslav Zaher on 12/27/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
struct PriorityQueue<Element> {
private let _hasHigherPriority: (Element, Element) -> Bool
private let _isEqual: (Element, Element) -> Bool
fileprivate var _elements = [Element]()
init(hasHigherPriority: @escaping (Element, Element) -> Bool, isEqual: @escaping (Element, Element) -> Bool) {
self._hasHigherPriority = hasHigherPriority
self._isEqual = isEqual
}
mutating func enqueue(_ element: Element) {
self._elements.append(element)
self.bubbleToHigherPriority(self._elements.count - 1)
}
func peek() -> Element? {
return self._elements.first
}
var isEmpty: Bool {
return self._elements.count == 0
}
mutating func dequeue() -> Element? {
guard let front = self.peek() else {
return nil
}
self.removeAt(0)
return front
}
mutating func remove(_ element: Element) {
for i in 0 ..< self._elements.count {
if self._isEqual(self._elements[i], element) {
self.removeAt(i)
return
}
}
}
private mutating func removeAt(_ index: Int) {
let removingLast = index == self._elements.count - 1
if !removingLast {
self._elements.swapAt(index, self._elements.count - 1)
}
_ = self._elements.popLast()
if !removingLast {
self.bubbleToHigherPriority(index)
self.bubbleToLowerPriority(index)
}
}
private mutating func bubbleToHigherPriority(_ initialUnbalancedIndex: Int) {
precondition(initialUnbalancedIndex >= 0)
precondition(initialUnbalancedIndex < self._elements.count)
var unbalancedIndex = initialUnbalancedIndex
while unbalancedIndex > 0 {
let parentIndex = (unbalancedIndex - 1) / 2
guard self._hasHigherPriority(self._elements[unbalancedIndex], self._elements[parentIndex]) else { break }
self._elements.swapAt(unbalancedIndex, parentIndex)
unbalancedIndex = parentIndex
}
}
private mutating func bubbleToLowerPriority(_ initialUnbalancedIndex: Int) {
precondition(initialUnbalancedIndex >= 0)
precondition(initialUnbalancedIndex < self._elements.count)
var unbalancedIndex = initialUnbalancedIndex
while true {
let leftChildIndex = unbalancedIndex * 2 + 1
let rightChildIndex = unbalancedIndex * 2 + 2
var highestPriorityIndex = unbalancedIndex
if leftChildIndex < self._elements.count && self._hasHigherPriority(self._elements[leftChildIndex], self._elements[highestPriorityIndex]) {
highestPriorityIndex = leftChildIndex
}
if rightChildIndex < self._elements.count && self._hasHigherPriority(self._elements[rightChildIndex], self._elements[highestPriorityIndex]) {
highestPriorityIndex = rightChildIndex
}
guard highestPriorityIndex != unbalancedIndex else { break }
self._elements.swapAt(highestPriorityIndex, unbalancedIndex)
unbalancedIndex = highestPriorityIndex
}
}
}
extension PriorityQueue: CustomDebugStringConvertible {
var debugDescription: String {
return self._elements.debugDescription
}
}

View File

@ -0,0 +1 @@
../../../Platform/DataStructures/PriorityQueue.swift

View File

@ -1,152 +0,0 @@
//
// Queue.swift
// Platform
//
// Created by Krunoslav Zaher on 3/21/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
/**
Data structure that represents queue.
Complexity of `enqueue`, `dequeue` is O(1) when number of operations is
averaged over N operations.
Complexity of `peek` is O(1).
*/
struct Queue<T>: Sequence {
/// Type of generator.
typealias Generator = AnyIterator<T>
private let _resizeFactor = 2
private var _storage: ContiguousArray<T?>
private var _count = 0
private var _pushNextIndex = 0
private let _initialCapacity: Int
/**
Creates new queue.
- parameter capacity: Capacity of newly created queue.
*/
init(capacity: Int) {
self._initialCapacity = capacity
self._storage = ContiguousArray<T?>(repeating: nil, count: capacity)
}
private var dequeueIndex: Int {
let index = self._pushNextIndex - self.count
return index < 0 ? index + self._storage.count : index
}
/// - returns: Is queue empty.
var isEmpty: Bool {
return self.count == 0
}
/// - returns: Number of elements inside queue.
var count: Int {
return self._count
}
/// - returns: Element in front of a list of elements to `dequeue`.
func peek() -> T {
precondition(self.count > 0)
return self._storage[self.dequeueIndex]!
}
mutating private func resizeTo(_ size: Int) {
var newStorage = ContiguousArray<T?>(repeating: nil, count: size)
let count = self._count
let dequeueIndex = self.dequeueIndex
let spaceToEndOfQueue = self._storage.count - dequeueIndex
// first batch is from dequeue index to end of array
let countElementsInFirstBatch = Swift.min(count, spaceToEndOfQueue)
// second batch is wrapped from start of array to end of queue
let numberOfElementsInSecondBatch = count - countElementsInFirstBatch
newStorage[0 ..< countElementsInFirstBatch] = self._storage[dequeueIndex ..< (dequeueIndex + countElementsInFirstBatch)]
newStorage[countElementsInFirstBatch ..< (countElementsInFirstBatch + numberOfElementsInSecondBatch)] = self._storage[0 ..< numberOfElementsInSecondBatch]
self._count = count
self._pushNextIndex = count
self._storage = newStorage
}
/// Enqueues `element`.
///
/// - parameter element: Element to enqueue.
mutating func enqueue(_ element: T) {
if self.count == self._storage.count {
self.resizeTo(Swift.max(self._storage.count, 1) * self._resizeFactor)
}
self._storage[self._pushNextIndex] = element
self._pushNextIndex += 1
self._count += 1
if self._pushNextIndex >= self._storage.count {
self._pushNextIndex -= self._storage.count
}
}
private mutating func dequeueElementOnly() -> T {
precondition(self.count > 0)
let index = self.dequeueIndex
defer {
self._storage[index] = nil
self._count -= 1
}
return self._storage[index]!
}
/// Dequeues element or throws an exception in case queue is empty.
///
/// - returns: Dequeued element.
mutating func dequeue() -> T? {
if self.count == 0 {
return nil
}
defer {
let downsizeLimit = self._storage.count / (self._resizeFactor * self._resizeFactor)
if self._count < downsizeLimit && downsizeLimit >= self._initialCapacity {
self.resizeTo(self._storage.count / self._resizeFactor)
}
}
return self.dequeueElementOnly()
}
/// - returns: Generator of contained elements.
func makeIterator() -> AnyIterator<T> {
var i = self.dequeueIndex
var count = self._count
return AnyIterator {
if count == 0 {
return nil
}
defer {
count -= 1
i += 1
}
if i >= self._storage.count {
i -= self._storage.count
}
return self._storage[i]
}
}
}

View File

@ -0,0 +1 @@
../../../Platform/DataStructures/Queue.swift