(defn tails [s]
(take (count s) (reductions (fn [s _] (rest s)) s s)))
(defn match[p s]
(cond
(empty? p) (empty? s)
(empty? s) false
:else
(case (first p)
\* (boolean (some (partial match (rest p)) (tails s)))
\? (recur (rest p) (rest s))
\\ (and (= (ffirst p) (first s))
(recur (drop 2 p) (rest s)))
(and (= (first p) (first s))
(recur (rest p) (rest s))))))
(println
(time (match
"as*d*?qwe*qwe" "as123dssqwe12345678qwe"))) (println
(time (match
"as*d*?qwe*qw" "as123dssqwe12345678qwe")))
KGRlZm4gdGFpbHMgW3NdCiAgKHRha2UgKGNvdW50IHMpIChyZWR1Y3Rpb25zIChmbiBbcyBfXSAocmVzdCBzKSkgcyBzKSkpCgooZGVmbiBtYXRjaFtwIHNdCiAgIChjb25kCiAgICAgKGVtcHR5PyBwKSAoZW1wdHk/IHMpCiAgICAgKGVtcHR5PyBzKSBmYWxzZQogICAgIDplbHNlIAogICAgICAoY2FzZSAoZmlyc3QgcCkKICAgICAgICAgIFwqIChib29sZWFuIChzb21lIChwYXJ0aWFsIG1hdGNoIChyZXN0IHApKSAodGFpbHMgcykpKQogICAgICAgICAgXD8gKHJlY3VyIChyZXN0IHApIChyZXN0IHMpKQogICAgICAgICAgXFwgKGFuZCAoPSAoZmZpcnN0IHApIChmaXJzdCBzKSkKICAgICAgICAgICAgICAgICAgKHJlY3VyIChkcm9wIDIgcCkgKHJlc3QgcykpKQogICAgICAgICAgKGFuZCAoPSAoZmlyc3QgcCkgKGZpcnN0IHMpKQogICAgICAgICAgICAgICAocmVjdXIgKHJlc3QgcCkgKHJlc3QgcykpKSkpKQoKKHByaW50bG4gKHRpbWUgKG1hdGNoICAiYXMqZCo/cXdlKnF3ZSIgImFzMTIzZHNzcXdlMTIzNDU2Nzhxd2UiKSkpCihwcmludGxuICh0aW1lIChtYXRjaCAgImFzKmQqP3F3ZSpxdyIgImFzMTIzZHNzcXdlMTIzNDU2Nzhxd2UiKSkp