Mercurial > lbo > hg > ccplay
changeset 10:3ad8456efad1
Keypad exercise
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sat, 18 Mar 2023 22:25:57 +0100 |
parents | 8499a9b9ae47 |
children | efa39c007546 |
files | CMakeLists.txt dynprog.cc |
diffstat | 2 files changed, 91 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Mon Mar 13 23:14:42 2023 +0100 +++ b/CMakeLists.txt Sat Mar 18 22:25:57 2023 +0100 @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.26) project(ccplay) -ADD_SUBDIRECTORY(lib) SET(CMAKE_CXX_COMPILER g++) -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -g -Wall") +ADD_SUBDIRECTORY(lib) LINK_LIBRARIES(fmt) ADD_EXECUTABLE(time time.cc)
--- a/dynprog.cc Mon Mar 13 23:14:42 2023 +0100 +++ b/dynprog.cc Sat Mar 18 22:25:57 2023 +0100 @@ -3,6 +3,7 @@ #include <functional> #include <iostream> +#include <numeric> #include <ranges> #include <sstream> #include <string> @@ -21,6 +22,14 @@ } }; +class PairHash : function<size_t(const MemoKey &)> { + public: + template<typename T, typename U> + size_t operator()(const pair<T, U>& p) const { + return hash<T>{}(p.first) ^ hash<U>{}(p.second); + } +}; + template <typename T> size_t lcss_inner( const vector<T> &a, const vector<T> &b, size_t i, size_t j, size_t length, @@ -147,7 +156,7 @@ longest, result, seqixs); vector<T> seq(longest); - for (int i = 0; i < seq.size(); i++) + for (size_t i = 0; i < seq.size(); i++) seq.at(i) = a.at(seqixs.at(i)); fmt::print("Longest incr. subsequence is: {}\n", seq); } @@ -171,7 +180,7 @@ highest, result, seqixs); vector<T> seq(seqixs.size()); - for (int i = 0; i < seq.size(); i++) { + for (size_t i = 0; i < seq.size(); i++) { if (i > 0 && seqixs.at(i) == 0) break; seq.at(i) = a.at(seqixs.at(i)); @@ -179,6 +188,83 @@ fmt::print("Max sum incr. subsequence is: {}\n", seq); } +template<typename T> +string digits2string(const vector<T>& v) { + ostringstream s; + for (const T& e : v) { + s << e; + } + return s.str(); +} + +void keypad(const unordered_map<int, vector<int>>& adj, vector<int> seq, int n) { + if (n <= 0) { + cout << digits2string(seq) << " "; + } else { + if (seq.empty()) { + for (int k : views::keys(adj)) { + keypad(adj, vector<int>{k}, n-1); + } + } else { + int last = seq.back(); + const vector<int>& neighbors = adj.at(last); + for (int neigh : neighbors ) { + seq.push_back(neigh); + keypad(adj, seq, n-1); + seq.pop_back(); + } + } + } +} + +size_t count_keypad(const unordered_map<int, vector<int>>& adj, int last, int n, unordered_map<pair<int,int>, size_t, PairHash>& memo) { + if (n == 0) + return 1; + + /*const auto memopos = memo.find(make_pair(last, n)); + if (memopos != memo.end()) + return memopos->second;*/ + + if (last < 0) { + const auto ks = views::keys(adj); + auto tf = views::transform(ks, [&adj, &memo, n](int key) -> size_t { return count_keypad(adj, key, n-1, memo); }); + size_t result = reduce(tf.begin(), tf.end()); + memo.insert(make_pair(make_pair(last, n), result)); + return result; + } else { + const auto& neighbors = adj.at(last); + const auto counts = views::transform(neighbors, [&adj, &memo, n](int neigh) -> size_t { return count_keypad(adj, neigh, n-1, memo); }); + size_t result = reduce(counts.begin(), counts.end()); + memo.insert(make_pair(make_pair(last, n), result)); + return result; + } +} + +// https://www.techiedelight.com/count-total-possible-combinations-n-digit-numbers-mobile-keypad/ +void evaluate_keypad(size_t n = 2) { + unordered_map<int, vector<int>> adjacency{ + {1, {1, 2, 4}}, + {2, {1, 2, 3, 5}}, + {3, {2, 3, 6}}, + {4, {1, 4, 5, 7}}, + {5, {2, 5, 6, 8, 4}}, + {6, {3, 6, 5, 9}}, + {7, {4, 7, 8}}, + {8, {7, 5, 8, 9, 0}}, + {9, {6, 8, 9}}, + {0, {0, 8}}, + }; + unordered_map<pair<int, int>, size_t, PairHash> memo; + + + //keypad(adjacency, vector<int>{}, n); + cout << endl; + + size_t ck = timeit_f(function([&adjacency, &memo, n]() { return count_keypad(adjacency, -1, n, memo); }), "count_keypad"); + fmt::print("count = {}\n", ck); + +} + int lcss_main(void) { vector<int> a{1, 6, 2, -1, 3, 55, 2, 4, 23, 5, 6, 7, 8, 9, 10}; @@ -201,6 +287,6 @@ vector<int> a{-1, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11}; // Expect: 0,2,6,9,13 or ,11 // or 0,4,6,9,13 - evaluate_msis(a); + evaluate_keypad(6); return 0; }