Created
January 23, 2018 17:24
-
-
Save lukeredpath/50cb44cd92117033d3ab93a139102d61 to your computer and use it in GitHub Desktop.
Find possible values for an ambiguous morse code word
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
enum Signal: String { | |
case dot = "." | |
case dash = "-" | |
case unknown = "?" | |
static func parseSignals(from string: String) -> [Signal] { | |
return string.flatMap() { char in | |
return Signal(rawValue: String(char)) | |
} | |
} | |
} | |
indirect enum Tree { | |
case root(dot: Tree, dash: Tree) | |
case node(value: String, dot: Tree, dash: Tree) | |
case empty | |
case either(Tree, Tree) | |
var possibleValues: [String] { | |
switch self { | |
case .node(let value, _, _): | |
return [value] | |
case .either(let firstTree, let secondTree): | |
return firstTree.possibleValues + secondTree.possibleValues | |
default: | |
return [] | |
} | |
} | |
func branch(forSignal signal: Signal) -> Tree { | |
switch self { | |
case .root(let dot, let dash): | |
switch signal { | |
case .dot: | |
return dot | |
case .dash: | |
return dash | |
case .unknown: | |
return .either(dot, dash) | |
} | |
case .node(_, let dot, let dash): | |
switch signal { | |
case .dot: | |
return dot | |
case .dash: | |
return dash | |
case .unknown: | |
return .either(dot, dash) | |
} | |
case .empty: | |
return .empty | |
case .either(let firstTree, let secondTree): | |
return .either( | |
firstTree.branch(forSignal: signal), | |
secondTree.branch(forSignal: signal) | |
) | |
} | |
} | |
} | |
let morseCodeLookupTable: Tree = .root( | |
dot: .node( | |
value: "E", | |
dot: .node( | |
value: "I", | |
dot: .node(value: "S", dot: .empty, dash: .empty), | |
dash: .node(value: "U", dot: .empty, dash: .empty) | |
), | |
dash: .node( | |
value: "A", | |
dot: .node(value: "R", dot: .empty, dash: .empty), | |
dash: .node(value: "W", dot: .empty, dash: .empty) | |
) | |
), | |
dash: .node( | |
value: "T", | |
dot: .node( | |
value: "N", | |
dot: .node(value: "D", dot: .empty, dash: .empty), | |
dash: .node(value: "K", dot: .empty, dash: .empty) | |
), | |
dash: .node( | |
value: "M", | |
dot: .node(value: "G", dot: .empty, dash: .empty), | |
dash: .node(value: "O", dot: .empty, dash: .empty) | |
) | |
) | |
) | |
// takes a morse code word made up of -, ., or ? | |
func possibilities(_ word: String) -> Array<String> { | |
let signals = Signal.parseSignals(from: word) | |
let node = signals.reduce(morseCodeLookupTable) { (node, signal) in | |
return node.branch(forSignal: signal) | |
} | |
return node.possibleValues | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment