Circular Buffer - Mutating func bug

Hello!
I’ve been trying to solve the circular buffer, my code works locally and in other online editors. The provided error is:

An error occurred while running your tests. This might mean that there was an issue in our infrastructure, or it might mean that you have something in your code that’s causing our systems to break.
Please check your code, and if nothing seems to be wrong, try running the tests again.

so I’ve tried to scale it down to find the source of the bug, and it seems like everytime I try to mutate a value inside of a mutating func it breaks the CI. Example Code:

struct CircularBuffer {
    var capacity: Int
    var current: Int = 0

    var arr: [Int] = []
    var readIndex: Int = 0
    var writeIndex: Int = 0

    init(capacity: Int) {
        self.capacity = capacity
        arr.append(contentsOf: Array(0..<capacity))
    }

    func clear() {}

    func read() throws -> Int {
        guard current > 0 else { throw CircularBufferError.bufferEmpty }
        return 0
    }

    mutating func write(_ value: Int) throws {
        guard current < capacity else {
            throw CircularBufferError.bufferEmpty
        }
       current = current + 1
    }

    
    func overwrite(_ value: Int) {}
    
}

enum CircularBufferError: Error { 
    case bufferEmpty
    case bufferFull
}

so in the code above if you comment line 25(current = current + 1, I also tried with current += 1 and adding self. beforehand) suddently it works, it doesn’t pass the tests but the original error stops appearing.

My previous solution was:

import Foundation
enum CircularBufferError: Error {
    case bufferFull
    case bufferEmpty
}

struct CircularBuffer {
    var size: Int 
    var count: Int = 0

    var arr: Array<Int>
    var removeIndex: Int = 0
    var insertIndex: Int = 0

    init(capacity: Int){
        self.size = capacity
        self.arr = Array(0..<size)
    }
    
    mutating func clear() {
        self.count = 0
        self.removeIndex = 0
        self.insertIndex = 0
        self.arr = Array(repeating: 0, count: capacity)
    }

    mutating func read() throws -> Int {
        guard count > 0 else{ throw CircularBufferError.bufferEmpty
        }
        let val = arr[removeIndex]
        removeIndex = increment(removeIndex)
        count -= 1
        return val
    }

    mutating func write(_ value: Int) throws {
        guard count < size else {
            throw CircularBufferError.bufferFull
        }
        self.count += 1
        self.arr[insertIndex] = value
        self.insertIndex = increment(insertIndex)
    }
    
    mutating func overwrite(_ value: Int) {
        self.arr[insertIndex] = value
        self.insertIndex = increment(insertIndex)
        self.count += 1
    }
    
    private func increment(_ head: Int) -> Int {
        return ((head + 1) >= size) ? 0 : (head + 1)
    }
}

Just to be clear, when you say the code works locally, are you running the unit tests? Or are you doing custom testing, separate from what the exercise actually checks?

I did some custom tests, some using the same inputs, others just to be sure but without directly using XCTest framework.

Unless you’re using the same test code and the same framework, it’s pretty hard to assert your code actually does the correct thing locally ;)

Sometimes the Exercism infrastructure is slow and a rerun “just works” without any code changes needed. That does happen from time to time!

Ok, going to double check with all the tests listed on exercism on my mac, I will report once I finish it

So I double checked with all the test listed on exercism, I saw that the last 4 wouldn’t pass, but code would compile fine.
after fixing the logic the code works locally and on exercirsm, i don’t know if was just a temporary problem like you said, but keep in mind I did run many times, at different times.
What’s weird to me is that instead of showing the test failure it would show the error that I attached in the first message.

I did retest on the website with the code that I said could replicate the problem, and it still keeps displaying the error message, maybe is something related to the force casted try! in the tests? Following this I tested locally and xcode does throw a fatal error in try! as expected so maybe some of the infrastructure is not answering well to an edge-case?

anyway my specific is problem fixed, Thank you!

Yup! The unit tests intentionally and specifically test edge cases.

1 Like