Skip to content

Instantly share code, notes, and snippets.

@simonbromberg
Last active July 10, 2020 04:57
Show Gist options
  • Save simonbromberg/9213a2d1952f7901a4f85440e2fc1d58 to your computer and use it in GitHub Desktop.
Save simonbromberg/9213a2d1952f7901a4f85440e2fc1d58 to your computer and use it in GitHub Desktop.
Given the mapping a = 1, b = 2, ... z = 26, and an encoded message, count the number of ways it can be decoded
/*
Given the mapping a = 1, b = 2, ... z = 26, and an encoded message, count the number of ways it can be decoded.
For example, the message '111' would give 3, since it could be decoded as 'aaa', 'ka', and 'ak'.
You can assume that the messages are decodable. For example, '001' is not allowed.
*/
import Foundation
let chars = [" ", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
func decode(_ string: String) -> [[Int]] {
var possibles = [[Int]]()
for character in string {
if let code = character.wholeNumberValue {
var newPossibles = [[Int]]()
if possibles.isEmpty {
possibles.append([code])
continue
}
for i in 0..<possibles.count {
let p = possibles[i]
if let last = p.last, last < 10 {
let newValue = last * 10 + code
if newValue <= 26 {
var newDecode = p
newDecode.removeLast()
newDecode.append(newValue)
newPossibles.append(newDecode)
}
}
possibles[i] = possibles[i] + [code]
}
possibles += newPossibles
}
}
return possibles
}
func outputMessages(_ possibles: [[Int]]) -> [String] {
return possibles.map { $0.reduce("") { $0 + chars[$1] } }
}
func decode2(_ input: String) -> [String] {
return outputMessages(decode(input))
}
func encode(_ str: String) -> String {
var output = ""
for char in str {
if let index = chars.firstIndex(of: String(char)) {
output += String(index)
}
}
return output
}
let results = decode2("85121215231518124")
print(results)
// Some extremely brute force decoding:
let words = try! String(contentsOfFile: "/usr/share/dict/words")
let arrayOfWords = words.split(separator: "\n")
func findWordsIn(_ str: String) -> [String]? {
for w in arrayOfWords {
let word = String(w)
if word.count == 1 && (word.lowercased() != "a" || word.lowercased() != "i") {
continue
}
if word.count <= str.count, str[str.startIndex..<word.endIndex] == word {
let substring = String(str[word.endIndex..<str.endIndex])
if let foundMore = findWordsIn(substring) {
return [String(word)] + foundMore
}
}
}
return nil
}
print(findWordsIn("helloworld"))
//let filtered = results.filter { r -> Bool in
// for word in arrayOfWords {
// return true
// }
// return false
//}
//for result in results {
// if let phrase = findWordsIn(result) {
// print(phrase)
// } else {
// print("\(result) nope")
// }
//}
//print(filtered)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment