Silver Challenge Solutions


#1

Hello, these are my solutions:

import Cocoa

// using if else with a for in loop

for i in 1...100 {
    if (i % 3 == 0) && (i % 5 == 0) {
        print("FIZZ BUZZ")
    } else if i % 3 == 0 {
        print("FIZZ")
    } else if i % 5 == 0 {
        print("BUZZ")
    } else {
        print(i)
    }
}

// using a switch with a while loop this time for variation

var number = 1
while number <= 100 {
    let divisibleBy3 = number % 3
    let divisibleBy5 = number % 5
    let divisible = (divisibleBy3, divisibleBy5)
    switch divisible {
    case (0, 0):
        print("FIZZ BUZZ")
    case (0, _):
        print("FIZZ")
    case (_, 0):
        print("BUZZ")
    default:
        print(number)
    }
    number += 1
}

Cheers,
Raf


#2

My solution (using switch). It seems to work, but I’d be interested to know whether it’s an efficient way of solving the problem, or any other comments. Thanks.

var loopTuple = (f: false, b: false)

for i in 1...100 {
    loopTuple = (f: i % 3 == 0, b: i % 5 == 0)
    switch loopTuple {
    case (f: true, b: true):
        print("FIZZ BUZZ")
    case (f: true, b: false):
        print("FIZZ")
    case (f: false, b: true):
        print("BUZZ")
    default:
        print(i)
    }

#3

Hi,

I think it is great that you put your solutions here, I learn a lot just by seeing different approaches to solving the same problem. My solution follows a similar approach, but I added some code to make the printed string prettier with commas and spaces. The if/else version is a bit messy, maybe someone else has a tidier solution?

Alain

var fizzBuzzString = ""
let numberOfLoops = 15

// Version of FIZZ BUZZ with if/else
// and prints numbers in between...

for i in 1 ... numberOfLoops {
    if !(i % 3 == 0 || i % 5 == 0) {
        fizzBuzzString += String(i)
    } else {
        if i % 3 == 0 {
            fizzBuzzString += "FIZZ"
            if i % 5 == 0 {
                fizzBuzzString += " "
            }
        }
        if i % 5 == 0 {
            fizzBuzzString += "BUZZ"
        }
    }
    if i != numberOfLoops {
         fizzBuzzString += ", "
    }
}
print("\(fizzBuzzString).\n")

// Version of FIZZ BUZZ with switch and tuple,
// and does not print numbers in between...

fizzBuzzString = ""
var printComma = false
var i = 1
while i <= numberOfLoops {
    let caseTuple = (i % 3,i % 5)
    switch caseTuple {
    case (0,0):
        fizzBuzzString += "FIZZ BUZZ"
        printComma = true
    case (_,0):
        fizzBuzzString += "BUZZ"
        printComma = true
    case (0,_):
        fizzBuzzString += "FIZZ"
        printComma = true
    default:
        break
    }
    if i == numberOfLoops {
        printComma = false
        fizzBuzzString += "."
    }
    if printComma == true {
        fizzBuzzString += ", "
    }
    printComma = false
    i += 1
}
print("\(fizzBuzzString)\n")

#4

Your code looks good, after defining your tuple, you could just check each of your cases as:

case(true, true)

Alternative when you do a mod on a number, and there’s no remainder, the result is 0. So your code also could have looked like:

var loopTuple = (f: 0, b: 0)

    for i in 1...100 {
        loopTuple = (i % 3, i % 5)
        switch loopTuple {
        case (0, 0):
            print("FIZZ BUZZ")
        case (0, _):
            print("FIZZ")
        case (_, 0):
            print("BUZZ")
        default:
            print(i)
        }
    }

Hope that helps!


#5

Is it a good idea to declare a tuple inside a loop?

for i in 1...100 {
    let loopTuple = (i % 3, i % 5)
    switch loopTuple {
    case (0, 0):
    ...
}

Or even so

for i in 1...100 {
    switch (i % 3, i % 5) {
    case (0, 0):
    ...
}

#6

Declaring a tuple in a loop is just like declaring anything else in a loop. Do you need access to the information later or not?

One of the disadvantages of declaring it in your loop is you lose readability of your code. When you declare it outside of the loop: var loopTuple = (f: 0, b: 0) you can infer the first value is for fizz and the second for buzz. Declaring it the way you did in your loop, you might have to do some reverse engineering to try and figure what each of the values meant.


#7

Here’s my first solution. A bit too many brackets.

import Cocoa

var counter: Int = 0

for i in 0...99 {
    counter += 1
    
    if counter % 3 == 0 && counter % 5 == 0 {
        print("FIZZ BUZZ")
    }
    else {
        if counter % 5 == 0 {
            print("BUZZ")
    }
        else {
            if counter % 3 == 0 {
                print("FIZZ")
            }
            else {
                print(counter)
                }
            }
        }
    }

#8

Just for the fun of it, I timed the if/else solution vs. the switch/tuple solution.

I used the solution of PuntaHamra for the if/else and the solution of Tiberius for the switch/tuple.

The timing was done in the playground version of these solutions.

The result showed the if/else solution runs about 2x faster than the switch/tuple solution for the 100 numbers.

Cheers,
Jim


#9

Given that the preceding pages were all about the "Control Transfer Statement, Redux" I thought I’d put one together which I’m in two minds about. I think it’s readability is high, but not convinced the structure is optimal with all the continue statements. I think my assembly programming roots are showing!

import Cocoa

for i in 1...100 {

    if i % 3 == 0 && i % 5 == 0 {
        print("FIZZ BUZZ")
        continue
    }
    
    if i % 3 == 0 {
        print("FIZZ")
        continue
    }
    
    if i % 5 == 0 {
        print("BUZZ")
        continue
    }
    
    print (i)
}

#10

I was trying to make one statement to print FIZZ and one to print BUZZ and have them work together without using a separate FIZZ BUZZ statement, and this is what I came up with. I had to do some digging to figure out how to get print() to not include a newline. I hope that is kosher as it hasn’t been covered in the book up to this point. Also, how do you paste the code into a post in a block like that? I couldn’t figure it out.
Thanks!


import Cocoa

for i in 1...100 {
    if i % 3 == 0 || i % 5 == 0 {
        if i % 3 == 0 {
            print("FIZZ ", terminator:"")
        }
        if i % 5 == 0 {
            print("BUZZ")
        }else {
        print("")
        }
    }else {
        print("\(i)")
        
    }

}

#11

Sorry, my indents got all screwed up when I pasted, I’ll fix it if I figure it out.


#12

Enter your code between a pair of three back ticks, like this:
```
print (“Hoot hoot!”)
```

For example:

print ("Hoot hoot!")

#13

Thanks for the help! Edited.


#14

I have a question …

Why is == 0 even necessary in some of these solutions?

i % 3 == 0 || i % 5 == 0

Why not just ---- (i % 3) || (i % 5) ---- ?

Like what I proposed below is much simpler, why won’t this work? I get a whole bunch of “expected patter” errors.

let number = 1…100

switch number {

case where (number % 3)
print(“Fizz”)

case where (number % 5)
print(“Buzz”)

case where (number % 3) && (number % 5)
print(“Fizz Buzz”)

default: (number !% 3) || (number !% 5)
print("(number)")
}

I mean wouldn’t something like that be simpler?


#15

The or logical operator (||) requires two boolean expressions as operands, but the value type of the expression i % 3 is not boolean.

Remember, you are coding in Swift!


#16

Ahhhhh, that helps thanks! :wink:


#17

I did this:

func getFizzValue(_ number : Int) -> String{
    if number % 3 == 0 {
        return "FIZZ"
    }
    if number % 5 == 0 {
        return "BUZZ"
    }
    if number % 5 + number % 3 == 0 {
        return "BUZZ FIZZ"
    }
    return String(number)
}

func getFizzValueWithSwitch(_ number : Int) -> String {

    let divisions : (byThree : Int, byFive : Int) = (number % 3, number % 5)
    var response : String!
    switch divisions {
    case (0,0):
        response = "BUZZ FIZZ"
    case (0, _):
        response = "FIZZ"
    case (_, 0):
        response = "BUZZ"
    default:
        response = String(number)
    }
    return response
}

var response : String = ""
let numberOfLoops : Int = 100

for x in 1...numberOfLoops {
    response += getFizzValue(x)
    if x == numberOfLoops {
        response += "."
        continue
    }
    response += ", "
}
print(response)

#18

I wanted my solution to use the following: for loop, if statement, switch statement, and a tuple.

for i in 1…100 {

var fizz = false
var buzz = false

if i % 3 == 0 {
    fizz = true
}

if i % 5 == 0 {
    buzz = true
}

let fbTuple = (fizz, buzz)

switch fbTuple {
case (true, false):
    print("FIZZ")
case (false, true):
    print("BUZZ")
case (true, true):
    print("FIZZ BUZZ")
default:
    print(i)
}

}


#19

I had a lot of trouble figuring out a way to get the Switch solution to work. Here is what I finally came up with:

var i = 1

while i < 101 {
    var byThree = i % 3
    var byFive = i % 5
    var check = (three: byThree, five: byFive)
    switch check {
    case let both where (check.three == 0) && (check.five == 0):
        print ("\(i): FIZZ BUZZ: Both = \(check)")
    case let threes where (check.three == 0) && (check.five != 0):
        print ("\(i): FIZZ: Threes = \(check)")
    case let fives where (check.three != 0) && (check.five == 0):
        print ("\(i): BUZZ: Fives = \(check)")
    default:
        print ("\(i):")
    }
    i = i + 1
}

The big problem I was having was trying to figure out how to perform any logical check within each “case” statement because the result of the “case” is a Bool, apparently. Adding a local variable to the “case” statement fixed it.

I was curious to see what would happen when you told the compiler to print a tuple, and it prints right out.


#20
var i = 1

while i < 101 {
    var byThree = i % 3
    var byFive = i % 5
    var check = (three: byThree, five: byFive)
    switch check {
    case let (first, second) where (first == 0) && (second == 0):
        print ("\(i): FIZZ BUZZ: Both = \(first, second)")
    case let (first, second) where (first == 0) && (second != 0):
        print ("\(i): FIZZ: Threes    = \(first, second)")
    case let (first, second) where (first != 0) && (second == 0):
        print ("\(i): BUZZ: Fives     = \(first, second)")
    default:
        print ("\(i):")
    }
    i = i + 1
}

Or:

var i = 1

while i < 101 {
    var byThree = i % 3
    var byFive = i % 5
    var check = (three: byThree, five: byFive)
    switch check {
    case let tuple where (tuple.three == 0) && (tuple.five == 0):
        print ("\(i): FIZZ BUZZ: Both = \(tuple)")
    case let tuple where (tuple.three == 0) && (tuple.five != 0):
        print ("\(i): FIZZ: Threes    = \(tuple)")
    case let tuple where (tuple.three != 0) && (tuple.five == 0):
        print ("\(i): BUZZ: Fives     = \(tuple)")
    default:
        print ("\(i):")
    }
    i = i + 1
}