Last active
August 29, 2015 14:20
-
-
Save gilesbowkett/b18af441e81747f10143 to your computer and use it in GitHub Desktop.
what's the best way to satisfy this Midje test?
This file contains 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
(facts "about finding sub-words" | |
(fact "(sub-words) finds all possible sub-words" | |
(sub-words "monocarp") => ["mono", | |
"monoc", | |
"monoca", | |
"monocar", | |
"onoc", | |
"onoca", | |
"onocar", | |
"onocarp", | |
"noca", | |
"nocar", | |
"nocarp", | |
"ocar", | |
"ocarp", | |
"carp"])) |
it kind of needs to do this, so I'm thinking it'll be a list comprehension:
welder.core=> (subs "monocarp" 0 4)
"mono"
welder.core=> (subs "monocarp" 0 5)
"monoc"
welder.core=> (subs "monocarp" 0 6)
"monoca"
welder.core=> (subs "monocarp" 0 7)
"monocar"
welder.core=> (subs "monocarp" 1 5)
"onoc"
welder.core=> (subs "monocarp" 1 6)
"onoca"
welder.core=> (subs "monocarp" 1 7)
"onocar"
welder.core=> (subs "monocarp" 1 8)
"onocarp"
welder.core=> (subs "monocarp" 2 6)
"noca"
welder.core=> (subs "monocarp" 2 7)
"nocar"
welder.core=> (subs "monocarp" 2 8)
"nocarp"
welder.core=> (subs "monocarp" 3 7)
"ocar"
welder.core=> (subs "monocarp" 3 8)
"ocarp"
welder.core=> (subs "monocarp" 4 8)
"carp"
my solution
(defn sub-words [word]
(vec (filter (fn [subword]
(and (< 3 (.length subword))
(not (= word subword))))
(for [start (range 0 5), end (range 4 9)] (subs word start end)))))
advice still welcome, though, I wouldn't be shocked if there were a cleaner way to do it.
There are more efficient ways to do it that just iterate over the correct bounds, but I quite like:
(defn sub-words
([^String s] (sub-words s 4))
([^String s ^Integer min-length]
(vec (for [start (range 0 (.length s))
length (range min-length (.length s))
:let [end (+ start length)]
:when (<= end (.length s))]
(subs s start end)))))
But even in your example, if you find yourself filter
ing the results of a for
then you might sometimes look at using :let
and :when
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the basic idea here is to get all substrings >= 4 characters and <= 8. (they don't actually have to be in any particular order, that's just how I wrote the test.)