(defn tails [s]
(take (count s) (reductions (fn [s _] (rest s)) s s)))
(defn match[p s]
(cond
(empty? p) true
(empty? s) false
:else
(case (first p)
\* (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))))))
(print
(time (match
"as*d*?qwe*qwe" "as123dssqwe12345678qwe"))) (print
(time (match
"as*d*?qwe*qw" "as123dssqwe12345678qwe")))
KGRlZm4gdGFpbHMgW3NdCiAgKHRha2UgKGNvdW50IHMpIChyZWR1Y3Rpb25zIChmbiBbcyBfXSAocmVzdCBzKSkgcyBzKSkpCgooZGVmbiBtYXRjaFtwIHNdCiAgIChjb25kCiAgICAgKGVtcHR5PyBwKSB0cnVlCiAgICAgKGVtcHR5PyBzKSBmYWxzZQogICAgIDplbHNlIAogICAgICAoY2FzZSAoZmlyc3QgcCkKICAgICAgICAgIFwqIChzb21lIChwYXJ0aWFsIG1hdGNoIChyZXN0IHApKSAodGFpbHMgcykpCiAgICAgICAgICBcPyAocmVjdXIgKHJlc3QgcCkgKHJlc3QgcykpCiAgICAgICAgICBcXCAoYW5kICg9IChmZmlyc3QgcCkgKGZpcnN0IHMpKQogICAgICAgICAgICAgICAgICAocmVjdXIgKGRyb3AgMiBwKSAocmVzdCBzKSkpCiAgICAgICAgICAoYW5kICg9IChmaXJzdCBwKSAoZmlyc3QgcykpCiAgICAgICAgICAgICAgIChyZWN1ciAocmVzdCBwKSAocmVzdCBzKSkpKSkpCgoocHJpbnQgKHRpbWUgKG1hdGNoICAiYXMqZCo/cXdlKnF3ZSIgImFzMTIzZHNzcXdlMTIzNDU2Nzhxd2UiKSkpCihwcmludCAodGltZSAobWF0Y2ggICJhcypkKj9xd2UqcXciICJhczEyM2Rzc3F3ZTEyMzQ1Njc4cXdlIikpKQ==