0

I'm getting the above error in the following code. The Heap struct is from the Swift Algorithm Club. I'm using the Heap to solve a Hackerrank challenge: Heaps: Find the Running Median.

import Foundation

// Enter your code here 

struct Heap<Element> {
    var elements : [Element]
    let priorityFunction : (Element, Element) -> Bool

    init(elements: [Element] = [], priorityFunction: @escaping (Element, Element) -> Bool) {
        self.elements = elements
        self.priorityFunction = priorityFunction
        buildHeap()
    }

    mutating func buildHeap() {
        for index in (0 ..< count / 2).reversed() {
            siftDown(elementAtIndex: index)
        }
    }

    var isEmpty : Bool {
        return elements.isEmpty
    }

    var count : Int {
        return elements.count
    }

    func peek() -> Element? {
        return elements.first
    }

    func isRoot(_ index: Int) -> Bool {
        return (index == 0)
    }

    func leftChildIndex(of index: Int) -> Int {
        return (2 * index) + 1
    }

    func rightChildIndex(of index: Int) -> Int {
        return (2 * index) + 2
    }

    func parentIndex(of index: Int) -> Int {
        return (index - 1) / 2
    }

    func isHigherPriority(at firstIndex: Int, than secondIndex: Int) -> Bool {
        return priorityFunction(elements[firstIndex], elements[secondIndex])
    }

    func highestPriorityIndex(of parentIndex: Int, and childIndex: Int) -> Int {
        guard childIndex < count && isHigherPriority(at: childIndex, than: parentIndex)
            else { return parentIndex }
        return childIndex
    }

    func highestPriorityIndex(for parent: Int) -> Int {
        return highestPriorityIndex(of: highestPriorityIndex(of: parent, and: leftChildIndex(of: parent)), and:     rightChildIndex(of: parent))
    }

    mutating func swapElement(at firstIndex: Int, with secondIndex: Int) {
        guard firstIndex != secondIndex
            else { return }
        elements.swapAt(firstIndex, secondIndex)
    }

    mutating func enqueue(_ element: Element) {
        elements.append(element)
        siftUp(elementAtIndex: count - 1)
    }

    mutating func siftUp(elementAtIndex index: Int) {
        let parent = parentIndex(of: index)
        guard !isRoot(index),
            isHigherPriority(at: index, than: parent)
            else { return }
        swapElement(at: index, with: parent)
        siftUp(elementAtIndex: parent)
    }

    mutating func dequeue() -> Element? {
        guard !isEmpty // 1
            else { return nil }
        swapElement(at: 0, with: count - 1) // 2
        let element = elements.removeLast() // 3
        if !isEmpty { // 4
            siftDown(elementAtIndex: 0) // 5
        }
        return element // 6
    }

    mutating func siftDown(elementAtIndex index: Int) {
        let childIndex = highestPriorityIndex(for: index) // 1
        if index == childIndex { // 2
            return
        }
        swapElement(at: index, with: childIndex) // 3
        siftDown(elementAtIndex: childIndex)
    }
}

var topHeap = Heap<Int>(priorityFunction: >)
var bottomHeap = Heap<Int>(priorityFunction: <)

let n = Int(readLine(strippingNewline: true)!)!
let val1 = Int(readLine(strippingNewline: true)!)!
print(String(format: "%.1f", Float(val1)))
if n > 1 {
    let val2 = Int(readLine(strippingNewline: true)!)!
    print(String(format: "%.1f", (Float(val1) + Float(val2)) / 2.0))
    if val1 < val2 {
        topHeap.enqueue(val1);
        bottomHeap.enqueue(val2);
    } else {
        topHeap.enqueue(val2);
        bottomHeap.enqueue(val1);    
    }
    for _ in 2..<n {
        let val = Int(readLine(strippingNewline: true)!)!

        // Put in the proper heap
        if val < topHeap.peek()! {
            topHeap.enqueue(val)
        } else if val > bottomHeap.peek()! {
            bottomHeap.enqueue(val)
        } else if topHeap.count < bottomHeap.count {
            topHeap.enqueue(val)
        } else {
            bottomHeap.enqueue(val)
        }

        // If one heap has two more than the other, move one value
        if topHeap.count == bottomHeap.count + 2 {
            var element: Int = bottomHeap.dequeue

error: cannot use mutating member on immutable value: 'bottomHeap' is immutable

            topHeap.enqueue(element)
        } else if bottomHeap.count == topHeap.count + 2 {
            bottomHeap.enqueue(topHeap.dequeue)

error: cannot use mutating member on immutable value: 'topHeap' is immutable

        }

        // If one heap has one more than the other, the top node of the larger heap holds the median
        if topHeap.count == bottomHeap.count + 1 {
            print(String(format: "%.1f", Float(topHeap.peek()!)))
        } else if bottomHeap.count == topHeap.count + 1 {
            print(String(format: "%.1f", Float(bottomHeap.peek()!)))        
        } else {
            print(String(format: "%.1f", (Float(topHeap.peek()!) + Float(bottomHeap.peek()!)) / 2.0))        
        }
    }
}

1 Answer 1

2

dequeue is a function. You need to add () to the calls.

Then you need to deal with the fact that dequeue() returns an optional Int.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.