Last active
July 10, 2020 04:57
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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