         return array
     }
     
+    var buckets : Int {
+        return table.count
+    }
+    
     var count : Int {
         var c = 0
         for arr in table {

            print("did end because tc / 2 < 3: " + table.count)
            return
        }
        if min < sumOfBucketCounts() / tc {
            print("decreasing bucket count!")
            try changeBucketCount(tc)
            return


import Foundation

struct HashTableElement<K> : Hashable {
    let key : Int
    var elem : K?
    var hashValue : Int { return key }
}

func ==<K>(lhs: HashTableElement<K>, rhs: HashTableElement<K>) -> Bool {
    return lhs.key == rhs.key
}

protocol HashTableType : CustomStringConvertible {
    associatedtype Element : Hashable
    
    // init(_ f: Element -> Int)
    // init(_ array: [Element]) throws
    // init()
    // init(_ buckets : Int)
    // init(_ buckets: Int, _ array: [Element]) throws
    // init(_ buckets : Int, hashFunction: Element -> Int)
    mutating func insert(elements: Element...) throws
    mutating func insert(elements: [Element]) throws
    mutating func insertNoCorrection(element new: Element) throws
    mutating func overwriteOrAdd(element: Element) throws
    mutating func executeForKey<T>(key: Element, f: (Int,Int?) throws -> T) throws -> T
    mutating func executeForUniqueKey<T>(key: Element, f: (Int,Int?) throws -> T) throws -> T
    mutating func overwrite(element: Element) throws
    mutating func insert(element new: Element) throws
    mutating func get(key key: Element) throws -> Element
    mutating func remove(key key: Element) throws -> Element
    mutating func correctBucketCount() throws
    func hash(key: Element) throws -> Int
    mutating func changeBucketCount(buckets: Int) throws
    mutating func changeBucketCount(buckets: Int, f: Element -> Int) throws
    mutating func hash(newHash: Element -> Int) throws
    func sort()
    var array : [Element] { get }
    var buckets : Int { get }
    var count : Int { get }
    var description: String { get }
}

struct HashTable <Element : Hashable> : HashTableType {
    
    //P.ERFORMANCE: making table of type [[[(K,V)]]] with the second list being hashed, too?
    private(set) var table          : [[Element]]
    private(set) var hashFunction   : Element -> Int
    
    init(_ f: Element -> Int) {
        self.init()
        hashFunction = f
    }
    
    init(_ array: [Element]) throws {
        self.init()
        for v in array {
            try insert(element: v)
        }
    }
    
    init(_ array: [Element], buckets: Int) throws {
        self.init(buckets)
        for v in array {
            try insert(element: v)
