String.ImproveMyCode(code)

Table of Content

Since initially writing this, I was informed that it’s part of a lesson that is in my distant future relating to the Theory of Computation/Hash Tables. As a disclaimer, I have little to no knowledge regarding this discipline so everything in this post should be taken with salt.

The question was asked:

Is there a better way to write this?

which included this code:

extension Bool {
    var asInt: Int { return self ? 1 : 0 }
}

extension Int {
    var asBool: Bool { return self == 0 ? false : true }
}

for A in 0..<2 {
    for B in 0..<2 {
        for C in 0..<2 {
            let result = !(A.asBool || B.asBool) || ( (A.asBool || C.asBool) && !(B.asBool || !C.asBool) )
            print("A \(A), B \(B), C \(C): Result: \(result)")
        }
    }
} 

"A better way to write this" is rather vague in its intent. Is the asker looking for something that runs more efficient when compiled and run? Do they want it to be more human readable/easy to reason about? Are they looking for a way to simplify it into fewer lines?

I’ll just state right away that I don’t have the expertise to really know if it can be improved upon in its efficiency. However, with the exception of when efficiency makes a real difference, I believe that code is for humans and compiled code is for computers. Therefore, I do have some opinions regarding simplifying it into something humans can reason about a bit better, but it will end up costing a few more lines.

I’ll take care of the most obvious things first.

  1. The first thing I did was to remove the Bool extension. It’s not used anywhere.
extension Int {
    var asBool: Bool { return self == 0 ? false : true }
}

for A in 0..<2 {
    for B in 0..<2 {
        for C in 0..<2 {
            let result = !(A.asBool || B.asBool) || ( (A.asBool || C.asBool) && !(B.asBool || !C.asBool) )
            print("A \(A), B \(B), C \(C): Result: \(result)")
        }
    }
} 
  1. The asker later followed up with

    trying to implement some Boolean logic.

    When first reading the code, I wasn’t sure what 2 had to do with booleans, but after actually analyzing the code, I see that they were trying to write a range that went from 0 to 1. That can be done in a more concise way as well.

    • 0..<number means to create a range from 0 to number, but only going as high as number – 1. This is very useful in many scenarios, especially when dealing with indicies that are 0 indexed.
    • Here, we just simply want to do a loop with the loop value being 0 and followed up by a loop with 1, which is more easily written as 0...1 – the three periods mean that the range is inclusive as opposed to exclusive.
extension Int {
    var asBool: Bool { return self == 0 ? false : true }
}

for A in 0...1 {
    for B in 0...1 {
        for C in 0...1 {
            let result = !(A.asBool || B.asBool) || ( (A.asBool || C.asBool) && !(B.asBool || !C.asBool) )
            print("A \(A), B \(B), C \(C): Result: \(result)")
        }
    }
} 
  1. I don’t know what this code is trying to accomplish. Is it part of a larger algorithm? Is it simply an exercise the user is playing around with? Could it be a code challenge they are looking for ways to improve? The answer to this could change the context of my understanding, however, as it is, I would make some of the following changes to help with understanding for new eyeballs reading the code.

    1. I would break the result into several lines and write out comments regarding what each line is doing:
          let result =
                  !(A.asBool || B.asBool) // if either a or b are true, make false. if they are both false, make true
                  || ( (A.asBool || C.asBool) // if either a or c are true
                  && !(B.asBool || !C.asBool) ) // invert c then OR with b - invert result
    2. I might further break it down like so:
      let X = !(A.asBool || B.asBool) // if either a or b are true, make false. if they are both false, make true
      let Y = (A.asBool || C.asBool) // if either a or c are true
      let Z = !(B.asBool || !C.asBool) // invert c then OR with b - invert result
      let result = X || ( Y && Z )
      print("A \(A), B \(B), C \(C): Result: \(result)")
  2. I still can’t fathom the purpose of this code, but I think it’s a bit more human readable as a result now. Here is the final result of what I came up with:

extension Int {
    var asBool: Bool { return self == 0 ? false : true }
}

for A in 0...1 {
    for B in 0...1 {
        for C in 0...1 {
            let X = !(A.asBool || B.asBool) // if either a or b are true, make false. if they are both false, make true
            let Y = (A.asBool || C.asBool) // if either a or c are true
            let Z = !(B.asBool || !C.asBool) // invert c then OR with b - invert result
            let result = X || ( Y && Z )
            print("A \(A), B \(B), C \(C): Result: \(result)")
        }
    }
}

I’m sure there are still things that could be tidied up yet, one of which could be better variable names, but I hope what I did makes sense to others!

Leave a Reply

Your email address will not be published. Required fields are marked *