title: Swift code to produce a number of possible anagrams from a selected word
body: <p>I've attempted to research ways to take a given word and calculate the number of possible anagrams a user can make from that word eg an 8 letter word such as snowbanks has 5 eight letter possibilities, 25 seven letter possibilities, etc (those are made up numbers). My initial plan would be to iterate over a dictionary list and check each of the words to see if it is an anagram of the word in question as I've seen suggested in other places.</p>
  
  <p><a href="https://stackoverflow.com/questions/15859238/rearrange-letters-from-array-and-check-if-arrangement-is-in-array?utm_medium=organic&amp;utm_source=google_rich_qa&amp;utm_campaign=google_rich_qa">Rearrange Letters from Array and check if arrangement is in array</a></p>
  
  <p>seemed very promising, except that it is in objective C and when I tried to convert it to Swift using Swiftify I couldn't get it to work as shown below:</p>
  
  <pre><code>    func findAnagrams() -&gt; Set&lt;AnyHashable&gt;? {
          let nineCharacters = [unichar](repeating: 0, count: 8)
          let anagramKey = self.anagramKey()
          // make sure this word is not too long/short.
          if anagramKey == nil {
              return nil
          }
          (anagramKey as NSString?)?.getCharacters(nineCharacters, range: NSRange)
          let middleCharPos = Int((anagramKey as NSString?)?.range(of: (self as NSString).substring(with: NSRange)).location ?? 0)
          var anagrams = Set&lt;AnyHashable&gt;()
          // 0x1ff means first 9 bits set: one for each character
          for i in 0...0x1ff {
              // skip permutations that do not contain the middle letter
              if (i &amp; (1 &lt;&lt; middleCharPos)) == 0 {
                  continue
              }
              var length: Int = 0
              var permutation = [unichar](repeating: 0, count: 9)
              for bit in 0...9 {
                  if true {
                      permutation[length] = nineCharacters[bit]
                      length += 1
                  }
              }
              if length &lt; 4 {
                  continue
              }
              let permutationString = String(permutation)
              let matchingAnagrams = String.anagramMap()[permutationString] as? [Any]
              for word: String? in matchingAnagrams {
                  anagrams.insert(word)
              }
          }
          return anagrams
      }
  
      class func anagramMap() -&gt; [AnyHashable: Any]? {
          var anagramMap: [AnyHashable: Any]
          if anagramMap != nil {
              return anagramMap
          }
          // this file is present on Mac OS and other unix variants
          let allWords = try? String(contentsOfFile: "/usr/share/dict/words", encoding: .utf8)
          var map = [AnyHashable: Any]()
          autoreleasepool {
              allWords?.enumerateLines(invoking: {(_ word: String?, _ stop: UnsafeMutablePointer&lt;ObjCBool&gt;?) -&gt; Void in
                  let key = word?.anagramKey()
                  if key == nil {
                      return
                  }
                  var keyWords = map[key] as? [AnyHashable]
                  if keyWords == nil {
                      keyWords = [AnyHashable]()
                      map[key] = keyWords
                  }
                  if let aWord = word {
                      keyWords?.append(aWord)
                  }
              })
          }
          anagramMap = map
          return anagramMap
      }
  
      func anagramKey() -&gt; String? {
          let lowercaseWord = word.lowercased()
          // make sure to take the length *after* lowercase. it might change!
          let length: Int = lowercaseWord.count
          // in this case we're only interested in anagrams 4 - 9 characters long
          if length &lt; 3 || length &gt; 9 {
              return nil
          }
          let sortedWord = [unichar](repeating: 0, count: length)
          (lowercaseWord as NSString).getCharacters(sortedWord, range: NSRange)
          qsort_b(sortedWord, length, MemoryLayout&lt;unichar&gt;.size, {(_ aPtr: UnsafeRawPointer?, _ bPtr: UnsafeRawPointer?) -&gt; Int in
              let a = Int(unichar(aPtr))
              let b = Int(unichar(bPtr))
              return b - a
          })
          return String(describing: sortedWord)
      }
  
  
  
  
  func isReal(word: String) -&gt; Bool {
      let checker = UITextChecker()
      let range = NSMakeRange(0, word.utf16.count)
      let misspelledRange = checker.rangeOfMisspelledWord(in: word, range: range, startingAt: 0, wrap: false, language: "en")
  
      return misspelledRange.location == NSNotFound
  }
  
  }
  </code></pre>
  
  <p>I've also tried the following in an attempt to just produce a list of words that I could iterate over to check for anagrams (I have working code that checks guesses vs the main word to check for anagrams) but I wasn't able to get them to work, possibly because they require a file to be copied to the app, since I was under the impression that the phone has a dictionary preloaded that I could use for words (although I may be mistaken):</p>
  
  <pre><code>var allTheWords = try? String(contentsOfFile: "/usr/share/dict/words", encoding: .utf8)
      for line: String? in allTheWords?.components(separatedBy: "\n") ?? [String?]() {
          print("\(line ?? "")")
          print("Double Fail \(allTheWords)")
      }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>    if let wordsFilePath = Bundle.main.path(forResource: "dict", ofType: nil) {
          do {
              let wordsString = try String(contentsOfFile: wordsFilePath)
  
              let wordLines = wordsString.components(separatedBy: NSCharacterSet.newlines)
  
              let randomLine = wordLines[Int(arc4random_uniform(UInt32(wordLines.count)))]
  
              print(randomLine)
  
          } catch { // contentsOfFile throws an error
              print("Error: \(error)")
          }
      }
  
  }
  </code></pre>
  
  <p>I looked at UIReferenceLibraryViewController as well in an attempt to use it to produce a list of words instead of defining a selected word, but the following isn't a valid option.</p>
  
  <pre><code>let words = UIReferenceLibraryViewController.enumerated
  </code></pre>
  
  <p>Any assistance would be greatly appreciated!</p>