diff --git a/longest_subsequence.cpp b/longest_subsequence.cpp new file mode 100644 index 0000000..34a66ee --- /dev/null +++ b/longest_subsequence.cpp @@ -0,0 +1,55 @@ + +auto subsequence_boundary(auto start, auto end,auto pred) { + using live_iterator = decltype(start); + using distance_t = std::invoke_result_t), live_iterator, decltype(end)>; + distance_t distance = std::distance(start, end); + + if(distance < 1) { + return start; + } + + if(distance == 1) { + return ++start; + } + + live_iterator next = start; + ++next; + + while(not pred(*start, *next)) { + ++start; + ++next; + if(next == end) return next; + } + + return next; +} + +auto longest_matching_subsequence(auto start, auto end, auto pred) { + using live_iterator = decltype(start); + using distance_t = std::invoke_result_t), live_iterator, decltype(end)>; + live_iterator current = start; + struct { + live_iterator best_s; + live_iterator best_e; + } results; + results.best_s = start; + results.best_e = start; + distance_t best_length = 0; + while(current != end) { + live_iterator next = subsequence_boundary(current, end, pred); + distance_t subsequence_length = std::distance(current, next); + if(subsequence_length > best_length) { + results.best_s = current; + results.best_e = next; + best_length = subsequence_length; + } + current = next; + } + return results; +} + +TEST_CASE("Subsequence") { + std::vector list = {0,1,2,3,4,5,0,1,0,2,5,8,7}; + auto [s,e] = longest_matching_subsequence(list.begin(), list.end(), std::greater{}); + REQUIRE(std::distance(s,e) == 6); +}