changeset 4:bb5c00d28022

dynprog
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 12 Mar 2023 14:12:10 +0100
parents 86e76ae3ac8a
children a1ac40ee3a1e
files CMakeLists.txt dynprog.cc sorting.cc
diffstat 3 files changed, 82 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Tue Mar 07 01:14:02 2023 +0100
+++ b/CMakeLists.txt	Sun Mar 12 14:12:10 2023 +0100
@@ -3,7 +3,9 @@
 
 ADD_SUBDIRECTORY(lib)
 
+SET(CMAKE_CXX_COMPILER g++)
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall")
+LINK_LIBRARIES(fmt)
 
 ADD_EXECUTABLE(time time.cc)
 TARGET_LINK_LIBRARIES(time exec)
@@ -16,3 +18,6 @@
 
 ADD_EXECUTABLE(sorting sorting.cc)
 TARGET_LINK_LIBRARIES(sorting exec)
+
+ADD_EXECUTABLE(dynprog dynprog.cc)
+TARGET_LINK_LIBRARIES(dynprog exec)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dynprog.cc	Sun Mar 12 14:12:10 2023 +0100
@@ -0,0 +1,77 @@
+
+#include <iostream>
+#include <ranges>
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include <fmt/core.h>
+#include <fmt/ranges.h>
+
+using namespace std;
+
+template<typename T>
+size_t lcss_inner(const vector<T>& a, const vector<T>& b, size_t i, size_t j, size_t length, size_t& longest, vector<T>& longest_seq) {
+    if (i >= a.size() || j >= b.size()) {
+        return length;
+    }
+
+    if (a.at(i) == b.at(j)) {
+        // Current (i, j) is member of a common subsequence.
+        longest = max(longest, length+1);
+        size_t remaining_longest = lcss_inner(a, b, i+1, j+1, length+1, longest, longest_seq);
+        if (remaining_longest == longest) {
+            // This element is part of the longest common subsequence.
+            longest_seq.at(length) = a.at(i);
+        }
+        return remaining_longest;
+    } else {
+        // Skip element from a.
+        size_t remaining_longest_skip_a = lcss_inner(a, b, i+1, j, length, longest, longest_seq);
+        // Skip element from b.
+        size_t remaining_longest_skip_b = lcss_inner(a, b, i, j+1, length, longest, longest_seq);
+        return max(remaining_longest_skip_a, remaining_longest_skip_b);
+    }
+}
+
+template<typename T>
+vector<T> lcss(const vector<T>& a, const vector<T>& b) {
+    size_t longest = 0;
+    vector<T> longest_seq(min(a.size(), b.size()));
+    size_t longest_r = lcss_inner(a, b, 0, 0, 0, longest, longest_seq);
+
+    fmt::print("Length: {} / {}\n", longest, longest_r);
+
+    return longest_seq;
+}
+
+template<typename T, typename T2, template<typename,typename> typename C>
+void evaluate_lcss(const C<T,T2>& a, const C<T,T2>& b) requires ranges::range<C<T,T2>> {
+    vector<T> va(a.begin(), a.end());
+    vector<T> vb(b.begin(), b.end());
+
+    fmt::print("{}\n", va);
+    fmt::print("{}\n", vb);
+    fmt::print("{}\n", lcss(va, vb));
+}
+// g++ only
+template<typename T, template<typename> typename C>
+void evaluate_lcss(const C<T>& a, const C<T>& b) requires ranges::range<C<T>> {
+    vector<T> va(a.begin(), a.end());
+    vector<T> vb(b.begin(), b.end());
+
+    fmt::print("{}\n", va);
+    fmt::print("{}\n", vb);
+    fmt::print("{}\n", lcss(va, vb));
+}
+
+int main(void) {
+
+    vector<int> a{1,6,2,-1,3,55,2,4,23,5,6,7,8,9,10};
+    vector<int> b{-3, 1, 5, 7, 2, 4, -1, 3, 6, 7, 9, 11, 10};
+
+    evaluate_lcss(a, b);
+    evaluate_lcss(views::iota(1, 10), views::iota(2, 11));
+    evaluate_lcss(views::single(11), views::single(11));
+    return 0;
+}
--- a/sorting.cc	Tue Mar 07 01:14:02 2023 +0100
+++ b/sorting.cc	Sun Mar 12 14:12:10 2023 +0100
@@ -163,7 +163,6 @@
 
 enum class SiftDirection { Up, Down };
 
-/// Build max-heap by sifting-down.
 template<typename T>
 void make_into_heap(vector<T>& v, SiftDirection direction = SiftDirection::Down) {
     if (direction == SiftDirection::Down)
@@ -176,7 +175,6 @@
         }
 }
 
-// Build max heap by sifting-up
 
 int main(void) {
     vector<string> v{"hello", "olleh", "abc", "bca", "world", "wrlod"};