Silver challenge: Dictionaries


#1

This is my solution to the Silver and Gold challenges. Obviously, nobody understands zip codes outside the US, so I translated them into proper British ones first :slight_smile: Any suggestions for improvements are welcome!

(BTW the formatting of the Gold solution is correct in the Xcode console, but doesn’t translate here…)

// Silver challenge
    var postcodeArray : [String] = []
    var Cheshire : Dictionary<String, Array<String>> = [:]
    Cheshire["Chester"] = ["CH1", "CH2", "CH3", "CH4", "CH5"]
    Cheshire["Crewe"] = ["CW1", "CW2", "CW3", "CW4", "CW5"]
    Cheshire["Northwich"] = ["NW1", "NW2", "NW3", "NW4", "NW5"]
    var postCodeString = "  ["

    for (key, value) in Cheshire {
        for code in value {
            if code != value.last {
                postCodeString += "\(code), "
            } else {
                postCodeString += "\(code)"
            }
        }
        if keyCount < Cheshire.count {
            postCodeString += ","
        } else {
            postCodeString += "]"
        }

    }

    print("Cheshire has the following post codes: \(postCodeString)")
    // Cheshire has the following post codes:   [CH1, CH2, CH3, CH4, CH5,CW1, CW2, CW3, CW4, CW5,NW1, NW2, NW3, NW4, NW5]

    // Gold challenge
    var postcodeArray : [String] = []
    var Cheshire : Dictionary<String, Array<String>> = [:]
    Cheshire["Chester"] = ["CH1", "CH2", "CH3", "CH4", "CH5"]
    Cheshire["Crewe"] = ["CW1", "CW2", "CW3", "CW4", "CW5"]
    Cheshire["Northwich"] = ["NW1", "NW2", "NW3", "NW4", "NW5"]
    var postCodeString = "  ["
    var keyCount = 1
    for (key, value) in Cheshire {
        for code in value {
            if code != value.last {
            postCodeString += "\(code), "
            } else {
                postCodeString += "\(code)"
            }
        }
        if keyCount < Cheshire.count {
            postCodeString += "\n\t\t\t\t\t\t\t"
        } else {
            postCodeString += "]"
        }
        keyCount += 1
    }

    print("Cheshire has the following post codes: \(postCodeString)")

    // Cheshire has the following post codes:   [CH1, CH2, CH3, CH4, CH5
 						CW1, CW2, CW3, CW4, CW5
   						NW1, NW2, NW3, NW4, NW5]

#2

Tip for Posting Code - Use 3 Backticks ```

When posting code, insert 3 backticks before and 3 backticks after the block of code, like this:

struct Foo {
   // Details
}

struct Bar {
   // Details
}

Nothing else on the line containing the backticks.


#3

Ah, thank you. I had used the format bar button rather than the markdown. Much better, thanks.


#4

Thanks for posting this solution. I was stuck on this one and feeling stupid.

Are solutions to all the challenges posted anywhere? Or is this the place? I was surprised that some of the earlier chapters’ forums are completely empty…

Enjoying the book and learning Swift.


#5

After thinking some more and reflecting on your solution, this is where I landed, but it feels a bit hacky…

let state = ["Harris": ["77024", "77026", "77023", "77011", "77044"],
             "Fort Bend": ["78665", "78664", "78554", "78443", "78699"],
              "Brazoria": ["76654", "76832", "76954", "76123", "76432"]]

let zips = Array(state.values)

let intro = "Texas has the following zip codes: ["

print(intro, terminator: "")

for zipset in zips {
  for i in 0...4 {
    if zipset[i] == state["Brazoria"]![4] {
      print("\(zipset[i])]")
    } else {
      print(zipset[i], terminator: ", ")
    }
  }
  print("")
  for i in 1...intro.characters.count {
    print(" ", terminator: "")
  }
}

#6

Hello. Can anybody say why I have this strange output with this code?

var ZipCodesOfColorado = ["county1" : [123, 321, 231], "county2" : [456, 546, 654], "county3" : [765, 876, 987]]
for zipCodes in ZipCodesOfColorado.values {
    print("The Colorado's zipCode: \(ZipCodesOfColorado.values)")
}


#7

I think it’s because you’re using .values, which you don’t need. All you need to do is iterate over the dictionary (ZipCodesOfColorado) itself and print out them out:

var str = "Hello, playground"
var ZipCodesOfColorado = ["county1" : [123, 321, 231], "county2" : [456, 546, 654], "county3" : [765, 876, 987]]
for zipCodes in ZipCodesOfColorado {
    print("The Colorado's zipCode: \(zipCodes)")
}

The Colorado's zipCode: ("county3", [765, 876, 987])
The Colorado's zipCode: ("county1", [123, 321, 231])
The Colorado's zipCode: ("county2", [456, 546, 654])

But I could be wrong…


#8

For what it’s worth, this is my solution for the Dictionary Silver Challenge:

// Dictionary Silver Challenge

var michiganZipsByCounty = ["Oakland": [48073, 48074, 48075, 48076, 48077], "Macomb": [48173, 48174, 48175, 48176, 48177], "Wayne": [48273, 48274, 48275, 48276, 48277]]

var michiganZipCodes: [Int] = []
for countyZips in michiganZipsByCounty.values {
    for zip in countyZips {
        michiganZipCodes.append(zip)
    }
}

print("Michigan has the following zip codes: \(michiganZipCodes)")

#9

Here is my solution to the Silver Challenge, for the brits.

    var postCodes : String = "["
    var codeValue : Int = 0
    var maxcodeValue : Int = 0
    var Devon : Dictionary<String, Array<String>> = [:]
    Devon["Exeter"] = ["EX1", "EX2", "EX3", "EX4", "EX5"]
    Devon["Plymouth"] = ["PL1", "PL2", "PL3", "PL4", "PL5"]
    Devon["Torquay"] = ["TQ1", "TQ2", "TQ3", "TQ4", "TQ5"]

    for (key, value) in Devon {
        for code in value {
            maxcodeValue += 1
        }
    }

    for (key, value) in Devon {
        for code in value {
            if codeValue == maxcodeValue-1 {
                postCodes += "\(code)]"
            } else {
                postCodes += "\(code), "
                codeValue += 1
            }
        }
    }

    print("Devon has the following post codes: \(postCodes)")

and the Gold challenge below:

    var postCodes : String = "["
    var codeValue : Int = 1
    var maxcodeValue : Int = 0
    var Devon : Dictionary<String, Array<String>> = [:]
    Devon["Exeter"] = ["EX1", "EX2", "EX3", "EX4", "EX5"]
    Devon["Plymouth"] = ["PL1", "PL2", "PL3", "PL4", "PL5"]
    Devon["Torquay"] = ["TQ1", "TQ2", "TQ3", "TQ4", "TQ5"]
    Devon

    for (key, value) in Devon {
        for code in value {
            maxcodeValue += 1
        }
    }

    for (key, value) in Devon {
        for code in value {
            if codeValue == maxcodeValue {
                postCodes += "\(code)]"
            } else if codeValue % 5 == 0 {
                postCodes += "\(code),     \n\t\t\t\t\t\t\t\t\t "
                codeValue += 1
            } else {
                postCodes += "\(code), "
                codeValue += 1
            }
        }
    }

    print("Devon has the following post codes: \(postCodes)")

#10

And my Gold Challenge solution. I’m guessing there’s a better way.

// Dictionary Gold Challenge

var michiganZipsByCounty = ["Oakland": [48073, 48074, 48075, 48076, 48077], "Macomb": [48173, 48174, 48175, 48176, 48177], "Wayne": [48273, 48274, 48275, 48276, 48277]]

var michiganZipCodes: [Int] = []
for countyZips in michiganZipsByCounty.values {
    for zip in countyZips {
        michiganZipCodes.append(zip)
    }
}

for (index, value) in michiganZipCodes.enumerated() {
    if index + 1 == 1 {
        print("Michigan has the following zip codes: [", value, separator: "", terminator: ", ")
    } else if index + 1 == 15 {
        print(value, "]", terminator: "")
    } else if (index + 1) % 5 == 0 {
        print(value, terminator: ",\n\t\t\t\t\t\t\t\t\t   ")
    } else {
        print(value, terminator: ", ")
    }
}

#11

Thank you! How can I use this formatting for code?


#12

I recognize this doesn’t exactly match the instructions given for the exercise, but in the interest of trying to get to the end using the least amount of code necessary, I solved the problem thusly. Wasn’t able to figure out how to incorporate a where clause, however, to limit the output to just MD.

var BaltimoreCity = [21221, 21222, 21223, 21224, 21225]
var BaltimoreCounty = [21101, 21102, 21103, 21104, 21105]
var Washington = [20001, 20002, 20003, 20004, 20005]

var zips = ["Maryland": [BaltimoreCity, BaltimoreCounty], "DistrictOfColumbia": Washington] as [String : Any]

for (state, zip) in zips {
    print("The State of \(state) has the following zip codes:  \(zip)")
}

Output:

The State of DistrictOfColumbia has the following zip codes:  [20001, 20002, 20003, 20004, 20005]
The State of Maryland has the following zip codes:  [[21221, 21222, 21223, 21224, 21225], [21101, 21102, 21103, 21104, 21105]]

#13

// Silver challenge
// NornIron = Northern Ireland, BTW :slight_smile:


var dicNornIron: [String:Array<String>]
dicNornIron = ["Down":["BT20", "BT19", "BT18", "BT17", "BT16"], "Antrim":["AN1", "AN2", "AN3", "AN4", "AN5"], "Fermanagh":["EN10", "EN11", "EN12", "EN13", "EN14"]]

var arrPostcodes: [String] = []
for postcode in dicNornIron.values {
    arrPostcodes += postcode
}
print ("Norn Iron has the following postcodes: \(arrPostcodes)")

// Bit extra, just for practice
for (county, postcodes) in dicNornIron {
    print ("County \(county) has the following postcodes: \(postcodes)")
}

Gives:

Norn Iron has the following postcodes: [“BT20”, “BT19”, “BT18”, “BT17”, “BT16”, “AN1”, “AN2”, “AN3”, “AN4”, “AN5”, “EN10”, “EN11”, “EN12”, “EN13”, “EN14”]
County Down has the following postcodes: [“BT20”, “BT19”, “BT18”, “BT17”, “BT16”]
County Antrim has the following postcodes: [“AN1”, “AN2”, “AN3”, “AN4”, “AN5”]
County Fermanagh has the following postcodes: [“EN10”, “EN11”, “EN12”, “EN13”, “EN14”]


#14

Tom, you need to define michiganZipCodes as a string if you defined the zip codes as a string:

var michiganZipCodes: [String] = []

I did, so your solution screwed me a bit up. Otherwise, very nice!


#15

//Silver Challenge - I was able to cut out some code by calling Array(nyCounty.values.joined())

var nyCounty = [
“Onondaga”: [13135, 13138, 13141, 13152, 13153],
“Jefferson”: [13601, 13602, 13603, 13605, 13606],
“Onieda”: [13054, 13123, 13157, 13162, 13301]
]

var zipcodes = Array(nyCounty.values.joined())
print(“NY has the following zip codes: (zipcodes)”) //(zipcodes) should have the “” preceding it

Which prints out “NY has the following zip codes: [13601, 13602, 13603, 13605, 13606, 13054, 13123, 13157, 13162, 13301, 13135, 13138, 13141, 13152, 13153]”


#16

My silver & gold challenge answers. I put a lot of comments on my gold challenge so you can see why I did what I did. All the comments make it look a lot longer than it is.

I used a switch statement for the gold challenge and created a variable to hold the number of white spaces needed to properly indent, depended on how many white spaces are in the intro. This way the indents will line up even if we change the intro.

//silver challenge
let countiesIllinois = ["A County" : [11111, 22222, 33333, 44444, 55555],
                        "B County" : [11101, 22202, 33303, 44404, 55505],
                        "C County" : [11110, 22220, 33330, 44440, 55550]
]
var allZipCodes: [Int] = []

for countyZips in countiesIllinois.values {
    for eachZip in countyZips {
        allZipCodes.append(eachZip)
    }
}

print("Illinois has these zip codes: \(allZipCodes)")

//add below for gold challenge

let intro = "Zip Codes in Illinois: "
print(intro, terminator:"") //print the intro and stay on the same line
var numOfWhiteSpaces = intro.characters.count // this is an Int variable that holds the count for the number of characters in our intro- "Zip codes in Illinois: "- that's 23 characters. Now we can let the compiler know to put 23 white spaced before every new line of zip codes. That will keep every line of zip codes lined up with the first line
var iterationsWhiteSpace = 1 //used to count iterations for the while loop below
var stringWhiteSpace = "" //This will be our string of white spaces. We will add 23 white spaces to this string using the while loop below and the two variables above

while iterationsWhiteSpace <= numOfWhiteSpaces {
    stringWhiteSpace += " "
    iterationsWhiteSpace += 1
}

var iteration = 1 //used for the switch/for-in loop below
let lastZipCode = allZipCodes.count //use the count property to get the place of the last zipcode. We will use this in the nested switch in the for-in loop below.

for zip in allZipCodes {
    switch iteration {   
    case 1: //if it's the 1st zip add a bracket, print, comma, and don't return to the next line.
        print("[\(zip),", terminator:" ")
        stringWhiteSpace += " " // add one more white space to account for the bracket we added
    case lastZipCode: //if it's the last zip print, add an end bracket, no comma, and return.
        print("\(zip)]")
    case let thisIteration where thisIteration % 5 != 0: // if it's not a fifth zip, print and don't return
        print("\(zip),", terminator:" ")
    default:// if it is a fifth zip in line, print, return, and add white space
            print("\(zip),")
            print(stringWhiteSpace, terminator:"")
    }
    iteration += 1 //add an iteration
}

#17

My solutions:

// silver challenge
let california = ["Hassoun County": [10001, 10002, 10003, 10004, 10005],
                  "Bilbo County": [20001, 20002, 20003, 20004, 20005],
                  "Hiho County": [30100, 30102, 30103, 30104, 30105]]

var zipCodes: [Int] = []
for codes in california.values {
    zipCodes += codes
}

print("California has the following zipcodes: \(zipCodes)")

// gold challenge
print("California has the following zipcodes: [", terminator: "")
for code in zipCodes[0...4] {
    print("\(code), ", terminator: "")
}
print("\n\t\t\t\t\t\t\t\t\t\t", terminator: "")
for code in zipCodes[5...9] {
    print("\(code), ", terminator: "")
}
print("\n\t\t\t\t\t\t\t\t\t\t", terminator: "")
for code in zipCodes[10...13] {
    print("\(code), ", terminator: "")
}
print("\(zipCodes[14])]")

#18

My gold solution:

var states: [String:Array<Int>] = [:]
states["AA"] = [10000, 11000, 12000, 13000, 10000, 15000, 16000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000]
states["BBBBBBBB"] = [50000, 60000, 70000, 80000, 90000, 51000, 52000, 53000, 54000, 55000, 56000, 57000]
states["CCCCCCCCCCCCC"] = [90000, 65000, 50000, 63000, 70000, 80000]
states["DDDDD"] = [90000, 65000, 50000]

for (key, value) in states {
    let stateString = "\(key) has the following zip codes: ["
    print(stateString, terminator: "")
    for i in 1...value.count {
        if i == value.count {
            print("\(value[i-1])]")
        } else if i % 5 == 0 {
            print("\(value[i-1]), ")
            for i in 1...stateString.characters.count {
                print(" ", terminator: "")
            }
        } else {
            print("\(value[i-1]), ", terminator: "")
        }
    }
}

#19

I believe this is the first challenge where the book recommends looking at the Apple documentation.

It suggests searching the documentation for the print() function.

In xcode, if you go to the menu Help -> Documentation and API Reference, you will get a search field. Here is what happens for the following entries in that search field:

"print"
many entries appear but nothing related to the print function of Swift

“print()” as suggested in the book
many entries appear but nothing related to the print function of Swift

"print("
many entries appear including one labeled “print(_:separator:terminator)” about halfway down. This is actually what you want, but as a novice Apple developer, this was not obvious to me.

Here is my suggestion:

  • in Xcode go to the menu Help -> Documentation and API Reference
  • enter “Array” in the search box
  • scroll to the top of the page and you will see
  • Swift Standard Library > Array
  • click on Swift Standard Library (which is a hyperlink)
  • you are now at the root of the Swift Standard Library in the Apple documentation
  • create a bookmark to this location

From this page, you will see a link to “print(_:separator:terminator:)” and if you follow it, it will describe the Swift print statement.


#20

Here’s my silver and gold answers. The gold answer is not elegant, I just built up a string and then printed it.

let douglasCounty = [“80134”, “80203”, “80138”, “80001”, “80002”]
let arapahoeCounty = [“80234”, “80126”, “81780”, “80003”, “80004”]
let adamsCounty = [“89075”, “83401”, “87210”, “80006”, “80007”]
var coloradoCounties = [“Douglas County”: douglasCounty,
“Arapahoe County”: arapahoeCounty,
“Adams County”: adamsCounty]

var numArray: [Int] = []
for strings in coloradoCounties.values {
for zipcode in strings {
if let num = Int(zipcode) {
numArray.append(num)
}
}
}

var printStr = "Colorado has the following zip codes: ["
let whiteSpaceCount = printStr.characters.count
printStr += "(numArray[0]), " + "(numArray[1]),\n"
for i in 2…4 {
printStr += "(numArray[i]), "
}
printStr += "\n"
for i in 1…whiteSpaceCount {
printStr += " "
}
for i in 5…6 {
printStr += "(numArray[i]), "
}
printStr += "\n"
for i in 7…9 {
printStr += "(numArray[i]), "
}
printStr += "\n"
for i in 1…whiteSpaceCount {
printStr += " "
}

for i in 10…11 {
printStr += "(numArray[i]), "
}
printStr += "\n"
for i in 12…13 {
printStr += "(numArray[i]), "
}
printStr += "(numArray[14])"
print(printStr)