Dinesman's multiple-dwelling problem
By parsing the problem
func dinesman(problem) {
var lines = problem.split('.')
var names = lines.first.scan(/\b[A-Z]\w*/)
var re_names = Regex(names.join('|'))
# Later on, search for these keywords (the word "not" is handled separately).
var words = %w(first second third fourth fifth sixth seventh eighth ninth tenth
bottom top higher lower adjacent)
var re_keywords = Regex(words.join('|'))
# Build an array of lambda's
var predicates = lines.first(-1).last(-1).map{ |line|
var keywords = line.scan(re_keywords)
var (name1, name2) = line.scan(re_names)...
keywords.map{ |keyword|
var l = do {
given(keyword) {
when ("bottom") { ->(c) { c.first == name1 } }
when ("top") { ->(c) { c.last == name1 } }
when ("higher") { ->(c) { c.index(name1) > c.index(name2) } }
when ("lower") { ->(c) { c.index(name1) < c.index(name2) } }
when ("adjacent") { ->(c) { c.index(name1) - c.index(name2) -> abs == 1 } }
default { ->(c) { c[words.index(keyword)] == name1 } }
}
}
line ~~ /\bnot\b/ ? func(c) { l(c) -> not } : l; # handle "not"
}
}.flat
names.permutations { |*candidate|
predicates.all { |predicate| predicate(candidate) } && return candidate
}
}Function invocation:
Output:
Simple solution
Output:
Last updated
Was this helpful?