Skip to content

Instantly share code, notes, and snippets.

@lukeredpath
Created January 23, 2018 17:24
Show Gist options
  • Save lukeredpath/50cb44cd92117033d3ab93a139102d61 to your computer and use it in GitHub Desktop.
Save lukeredpath/50cb44cd92117033d3ab93a139102d61 to your computer and use it in GitHub Desktop.
Find possible values for an ambiguous morse code word
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