Categories
Career Programming

Programmer interview challenge 1, revisited again: “Anagram” in Swift, the easy and hardcore way

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:

  1. It takes the given word — stored in the parameter word — and converts it to all lowercase letters using String’s lowercased() method.
  2. The all-lowercase word is converted into a sorted array of Characters by String’s sorted() method.
  3. The sorted array of Characters is converted back into a string using String’s initializer.
  4. Any leading whitespace in the string (the result of sorting a String with spaces in it) is removed with String’s trimmingCharacters(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.

Previously, in the “Programmer interview challenge” series

2 replies on “Programmer interview challenge 1, revisited again: “Anagram” in Swift, the easy and hardcore way”

Comments are closed.