In the past two articles, I’ve been writing about a challenge that’s often given to programmers at a tech interview: Write a program that determines if two words are anagrams.
In the first article, I wrote a basic Python solution. In the second article, I refined the Python solution and then based a JavaScript solution on it. In this article, I’ll present a couple of Swift solutions.
A simple Swift solution
Here’s a Swift solution that follows the same logic as the Python and JavaScript solutions I presented in the previous article:
func anagram(word1: String, word2: String) -> Bool { func sortLetters(in word: String) -> String { return String(word.lowercased().sorted()).trimmingCharacters(in: .whitespaces) } return sortLetters(in: word1) == sortLetters(in: word2) }
The Swift version of anagram()
takes the same approach as the Python and JavaScript version by making use of a function named sortLetters(in:)
that sorts the letters of a string in place. Here’s what it does:
- It takes the given word — stored in the parameter
word
— and converts it to all lowercase letters usingString
’slowercased()
method. - The all-lowercase word is converted into a sorted array of
Character
s byString
’ssorted()
method. - The sorted array of
Character
s is converted back into a string usingString
’s initializer. - Any leading whitespace in the string (the result of sorting a
String
with spaces in it) is removed withString
’strimmingCharacters(in:)
method.
Once sortLetters(in:)
is defined, all anagram()
has to do is apply it to both words and see if the results are the same.
Jessy Catterwaul’s hardcore Swift solution
When something about Swift confuses me (it happens!) my go-to person is Jessy Catterwaul, video course creator at raywenderlich.com (where I’m an author). His approach to the anagram problem was to use histograms and bucketing — or in simpler terms, to use a data structure to store the counts of each letter in both words. If both words have the same number of the same letters, they’re anagrams of each other.
He sent me this code, which defines an extension for Swift’s Dictionary
class. It gives Dictionary
a new initializer method, init(bucketing:)
. If you provide this initializer with a string, it creates a dictionary whose keys are the letters in the string, and whose corresponding values are the counts of those letters. For example, if you provide the initializer with the string abbccc, it returns a the dictionary ["a": 1, "b": 2, "c": 3]
.
Here’s the code:
public extension Dictionary where Value == Int { /// Create “buckets” from a sequence of keys, /// such as might be used for a hsitogram. init<Keys: Sequence>(bucketing unbucketedKeys: Keys) where Keys.Element == Key { self.init( zip(unbucketedKeys, AnyIterator { 1 }), uniquingKeysWith: + ) } }
Once the extension is defined, the following code…
let mississippiLetterCount = Dictionary(bucketing: "Mississippi") print("Mississippi letter count: \(mississippiLetterCount)")
…gives you this output:
Mississippi letter count: [“s”: 4, “i”: 4, “M”: 1, “p”: 2]
What’s up next
Next week, I’ll showcase another programming challenge that I’ve seen in technical interviews: The dreaded FizzBuzz! I’ll also devote some time to covering the “why” of programming challenges.
2 replies on “Programmer interview challenge 1, revisited again: “Anagram” in Swift, the easy and hardcore way”
[…] the second article, I refined the Python solution and then based a JavaScript solution on it. In the third article, I showed a couple of Swift implementations — one simple, one hardcore. In this article, I’ll […]
[…] Programmer interview challenge 1, revisited again: “Anagram” in Swift, the easy and hardcore way […]