commit bd81d402beedf9af1d8a6796ebf414a60f82cb04 Author: Knyffen Date: Thu Mar 21 13:49:58 2024 +0100 Init from KnyfSky diff --git a/CPP.cpp.snip b/CPP.cpp.snip new file mode 100644 index 0000000..295778d --- /dev/null +++ b/CPP.cpp.snip @@ -0,0 +1,24 @@ +// #define NDEBUG + +#include +// #include +#include +// #include +// #include +#include +// #include +// #include +// #include +// #include +// #include + +using namespace std; + +int main() { + ; + + return EXIT_SUCCESS; +} + +#ifndef NDEBUG +#endif diff --git a/CPP/TODO/foo.cpp b/CPP/TODO/foo.cpp new file mode 100644 index 0000000..4d2b37e --- /dev/null +++ b/CPP/TODO/foo.cpp @@ -0,0 +1,105 @@ +/* #define NDEBUG */ + +#include +/* #include */ +#include +/* #include */ +/* #include */ +#include +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +#include + +using namespace std; + + + +template +class adjacency_list { + public: + size_t N; + std::vector> adj; + + adjacency_list (size_t n) { + N = n; + adj(N, std::vector()); + } + + std::vector operator[](T i) { adj[i]; }; + void add_directed_edge(size_t i, size_t j) { + adj[i].push_back(j); + }; + void add_undirected_edge(size_t i, size_t j) { + adj[i].push_back(j); + adj[j].push_back(i); + }; +}; + +template +std::vector> floyd_warshall(std::vector> adj); + + +int main() { + vector> adj_matrix; + auto foo = floyd_warshall(adj_matrix); + /* floyd_warshall(adj_matrix); */ + ; + + return EXIT_SUCCESS; +} + +#ifndef NDEBUG +#endif + +// NOTE: !!!UNTESTED!!! +// Time complexity: O(n^3) +// Memory complexity: O(n^2) - only for n ~ 10^3 (n ~ 10^4 results in 1524 MB of memory) +// Input: Graph as an adjancency matrix (weight 0 => no edge) +// Output: A distance matrix (distance std::numeric_limits::max() => no path) +#include +#include +#include +#include +template +std::vector> floyd_warshall(std::vector> adj) { + size_t n = adj.size(); + std::vector> distance(n, std::vector(n, 0)); + + // Initialize distance + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < n; j++) { + if (i == j) distance[i][j] = 0; + else if (adj[i][j]) distance[i][j] = adj[i][j]; + else distance[i][j] = std::numeric_limits::max(); + } + } + + // Find shortest distances + for (size_t k = 0; k < n; k++) { + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < n; j++) { + if (distance[i][k] == std::numeric_limits::max() || distance[k][j] == std::numeric_limits::max()) + continue; + distance[i][j] = std::min(distance[i][j], + distance[i][k] + distance[k][j]); + } + } + } + + return distance; +} + + + +template +class 1D_sum_queries { + vector> array; + public: + 1D_sum_queries(size_t n) { + + } + std::vector operator[](T i) { adj[i]; }; +} diff --git a/CPP/graph_theory/floyd_warshall.cpp.snip b/CPP/graph_theory/floyd_warshall.cpp.snip new file mode 100644 index 0000000..974a3f8 --- /dev/null +++ b/CPP/graph_theory/floyd_warshall.cpp.snip @@ -0,0 +1,37 @@ +// NOTE: Check the input graph for multiple edges between the same vertices! You will want to keep the shortest one +// Time complexity: O(n^3) +// Memory complexity: O(n^2) - only for n ~ 10^3 (n ~ 10^4 results in 1524 MB of memory) +// Input: Graph as an adjancency matrix (weight __LONG_MAX__ => no edge) +// Output: A distance matrix (distance __LONG_MAX__ => no path) +vector> floyd_warshall(vector> adj) { + size_t n = adj.size(); + vector> distance(n, vector(n, 0)); + + // Initialize distance + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < n; j++) { + // Original floyd-warshall + // if (i == j) distance[i][j] = 0; + // else if (adj[i][j]) distance[i][j] = adj[i][j]; + // else distance[i][j] = __LONG_MAX__; + + // My version + if (i == j) distance[i][j] = 0; + else distance[i][j] = adj[i][j]; + } + } + + // Find shortest distances + for (size_t k = 0; k < n; k++) { + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < n; j++) { + if (distance[i][k] == __LONG_MAX__ || distance[k][j] == __LONG_MAX__) + continue; + distance[i][j] = min(distance[i][j], + distance[i][k] + distance[k][j]); + } + } + } + + return distance; +} diff --git a/CPP/graph_theory/graph.cpp.snip b/CPP/graph_theory/graph.cpp.snip new file mode 100644 index 0000000..3279a98 --- /dev/null +++ b/CPP/graph_theory/graph.cpp.snip @@ -0,0 +1,267 @@ +// #define NDEBUG + +#include +#include +#include +#include +#include +#include + +template class Graph; +template class WeightedGraph; +template class BaseGraph; + +template +class Graph : public BaseGraph { + virtual int construct_edge(int v, T w) { + w; // Remove warning + return v; + } + + virtual int get_edge_vertex(int e) { + return e; + } + + virtual T get_edge_weight(int e) { + e; // Remove warning + return 1; + } + + public: + Graph(size_t N, size_t min_index) : BaseGraph(N, min_index) {}; +}; + +template +class WeightedGraph : public BaseGraph> { + virtual std::pair construct_edge(int v, T w) { + return {w, v}; + } + + virtual int get_edge_vertex(std::pair e) { + return e.second; + } + + virtual T get_edge_weight(std::pair e) { + return e.first; + } + + bool min_cut_max_flow_dfs(std::vector&, std::pair&>>> &edge_pairs, std::vector&, std::pair&>>& path, std::vector& visited, int v, int sink, T threshold) { + if (v == sink) + return EXIT_SUCCESS; + visited[v] = true; + for (auto e : edge_pairs[v]) { + int u = get_edge_vertex(e.first); + int w = get_edge_weight(e.first); + if (!visited[u] && w >= threshold) { + bool res = min_cut_max_flow_dfs(edge_pairs, path, visited, u, sink, threshold); + if (res == EXIT_SUCCESS) { + path.push_back(e); + return EXIT_SUCCESS; + } + } + } + return EXIT_FAILURE; + } + + public: + WeightedGraph(size_t N, size_t min_index) : BaseGraph>(N, min_index) {}; + + Graph get_shortest_path_graph(int from) { + std::vector best_distance = this->dijkstra(from); + Graph G(this->N, this->min_index); + for (size_t i = this->min_index; i < this->N; i++) { + for (auto e : this->adj[i]) { + T w = get_edge_weight(e); + int v = get_edge_vertex(e); + if (best_distance[i] + w == best_distance[v]) + G.add_directed_edge(i, v); + } + } + return G; + } + + WeightedGraph get_weighted_shortest_path_graph(int from) { + std::vector best_distance = this->dijkstra(from); + WeightedGraph G(this->N, this->min_index); + for (size_t i = this->min_index; i < this->N; i++) { + for (auto e : this->adj[i]) { + T w = get_edge_weight(e); + int v = get_edge_vertex(e); + if (best_distance[i] + w == best_distance[v]) + G.add_directed_edge(i, v, w); + } + } + return G; + } + + // Running time: O(m^2n) + T min_cut_max_flow(int source, int sink) { + // TODO: Implement non-destructive version? + // Ford-Fulkerson - "scaling algorithm" version + std::vector&, std::pair&>>> edge_pairs(this->N, std::vector&, std::pair&>>()); + T threshold = 0; + for (size_t v = this->min_index; v < this->N; v++) { + for (auto& e : this->adj[v]) { + if (get_edge_weight(e) == 0) continue; + threshold = threshold > get_edge_weight(e) ? threshold : get_edge_weight(e); // max(threshold, get_edge_weight(e)); + int u = get_edge_vertex(e); + this->adj[u].push_back(construct_edge(v, 0)); + edge_pairs[v].push_back({e, this->adj[u][this->adj[u].size()-1]}); + edge_pairs[u].push_back({this->adj[u][this->adj[u].size()-1], e}); + } + } + + std::vector visited(this->N, false); + std::vector&, std::pair&>> path; + while (true) { + bool res = min_cut_max_flow_dfs(edge_pairs, path, visited, source, sink, threshold); + if (res == EXIT_SUCCESS) { + T path_max_flow = std::numeric_limits::max(); + for (auto e : path) + path_max_flow = path_max_flow < get_edge_weight(e.first) ? path_max_flow : get_edge_weight(e.first); + // min(path_max_flow, get_edge_weight(e.first)); + for (auto e : path) { + e.first = construct_edge(get_edge_vertex(e.first), get_edge_weight(e.first)-threshold); + e.second = construct_edge(get_edge_vertex(e.second), get_edge_weight(e.second)+threshold); + } + } else { + if (threshold == 1) + break; // Done! + threshold /= 2; + } + std::fill(visited.begin(), visited.end(), false); + path.clear(); + } + + T max_flow = 0; + for (auto e : this->adj[sink]) { + max_flow += get_edge_weight(e); + } + + return max_flow; + } +}; + +template +class BaseGraph { + std::vector top_sort; + int contains_cycles = 0; // 0 = unknown, 1 = yes, 2 = no + bool contains_negative_edge_weight = false; + + virtual int get_edge_vertex(EDGE) = 0; + virtual T get_edge_weight(EDGE) = 0; + virtual EDGE construct_edge(int vertex, T w) = 0; + + bool topological_sort_dfs(std::vector& status, int v, std::vector& top_sort) { + if (status[v] == 1) + return EXIT_FAILURE; + if (status[v] == 0) { + status[v] = 1; + for (auto e : adj[v]) { + bool res = topological_sort_dfs(status, get_edge_vertex(e), top_sort); + if (res == EXIT_FAILURE) + return EXIT_FAILURE; + } + status[v] = 2; + top_sort.push_back(v); + } + return EXIT_SUCCESS; + } + + void do_topological_sort() { + std::vector status(N, 0); + std::vector top_sort = std::vector(); + for (size_t i = min_index; i < N; i++) { + bool res = topological_sort_dfs(status, i, top_sort); + if (res == EXIT_FAILURE) { + contains_cycles = 1; + return; + } + } + + contains_cycles = 2; + std::reverse(top_sort.begin(), top_sort.end()); + this->top_sort = top_sort; + } + + public: + size_t N; + size_t min_index; + std::vector> adj; + + BaseGraph(size_t N, size_t min_index) { + N += min_index; + this->N = N; + this->min_index = min_index; + adj = std::vector>(N, std::vector()); + } + + void add_directed_edge(int from, int to, T w = 1) { + adj[from].push_back(construct_edge(to, w)); + contains_cycles = 0; + if (w < 0) + contains_negative_edge_weight = true; + } + + void add_undirected_edge(size_t a, size_t b, T w = 1) { + adj[a].push_back(construct_edge(b, w)); + adj[b].push_back(construct_edge(a, w)); + contains_cycles = 0; + if (w < 0) + contains_negative_edge_weight = true; + } + + std::vector get(int v) { + return adj[v]; + } + + std::vector topological_sort() { + if (contains_cycles != 2) + std::cerr << "Check for cycles first!" << std::endl; + return top_sort; + } + + bool has_cycles() { + if (contains_cycles == 0) + do_topological_sort(); + return contains_cycles == 1; + } + + std::vector count_paths(int from) { + if (contains_cycles != 2) + std::cerr << "Check for cycles first!" << std::endl; + std::vector paths(N, 0); + for (auto v : top_sort) { + T p = 0; + if (v == from) p++; + for (auto e : adj[v]) + p += paths[get_edge_vertex(e)]; + paths[v] = p; + } + return paths; + } + + std::vector dijkstra(int from) { + if (contains_negative_edge_weight) + std::cerr << "Dijkstra only works if the graph doesn't contain any negative edge weights" << std::endl; + std::vector distance(N, std::numeric_limits::max()); + distance[from] = 0; + std::vector processed(N, false); + std::priority_queue> q; + q.push({0, from}); + while (!q.empty()) { + int v = q.top().second; q.pop(); + if (processed[v]) continue; + processed[v] = true; + for (auto e : adj[v]) { + int u = get_edge_vertex(e); + T w = get_edge_weight(e); + if (distance[v] + w < distance[u]) { + distance[u] = distance[v] + w; + q.push({-distance[u], u}); + } + } + } + return distance; + } +}; diff --git a/CPP/graph_theory/test/test b/CPP/graph_theory/test/test new file mode 100644 index 0000000..d7e015a Binary files /dev/null and b/CPP/graph_theory/test/test differ diff --git a/CPP/graph_theory/test/test.cpp b/CPP/graph_theory/test/test.cpp new file mode 100644 index 0000000..b7d719e --- /dev/null +++ b/CPP/graph_theory/test/test.cpp @@ -0,0 +1,372 @@ +// #define NDEBUG + +#include +// #include +#include +// #include +// #include +#include +// #include +// #include +// #include +// #include +// #include + + +// #define NDEBUG + +#include +#include +#include +#include +#include +#include + +template class Graph; +template class WeightedGraph; +template class BaseGraph; + +template +class Graph : public BaseGraph { + virtual int construct_edge(int v, T w) { + w; // Remove warning + return v; + } + + virtual int get_edge_vertex(int e) { + return e; + } + + virtual T get_edge_weight(int e) { + e; // Remove warning + return 1; + } + + public: + Graph(size_t N, size_t min_index) : BaseGraph(N, min_index) {}; +}; + +template +class WeightedGraph : public BaseGraph> { + virtual std::pair construct_edge(int v, T w) { + return {w, v}; + } + + virtual int get_edge_vertex(std::pair e) { + return e.second; + } + + virtual T get_edge_weight(std::pair e) { + return e.first; + } + + bool min_cut_max_flow_dfs(std::vector&, std::pair&>>> &edge_pairs, std::vector&, std::pair&>>& path, std::vector& visited, int v, int sink, T threshold) { + if (v == sink) + return EXIT_SUCCESS; + visited[v] = true; + for (auto e : edge_pairs[v]) { + int u = get_edge_vertex(e.first); + int w = get_edge_weight(e.first); + if (!visited[u] && w >= threshold) { + bool res = min_cut_max_flow_dfs(edge_pairs, path, visited, u, sink, threshold); + if (res == EXIT_SUCCESS) { + path.push_back(e); + return EXIT_SUCCESS; + } + } + } + return EXIT_FAILURE; + } + + public: + WeightedGraph(size_t N, size_t min_index) : BaseGraph>(N, min_index) {}; + + Graph get_shortest_path_graph(int from) { + std::vector best_distance = this->dijkstra(from); + Graph G(this->N, this->min_index); + for (size_t i = this->min_index; i < this->N; i++) { + for (auto e : this->adj[i]) { + T w = get_edge_weight(e); + int v = get_edge_vertex(e); + if (best_distance[i] + w == best_distance[v]) + G.add_directed_edge(i, v); + } + } + return G; + } + + WeightedGraph get_weighted_shortest_path_graph(int from) { + std::vector best_distance = this->dijkstra(from); + WeightedGraph G(this->N, this->min_index); + for (size_t i = this->min_index; i < this->N; i++) { + for (auto e : this->adj[i]) { + T w = get_edge_weight(e); + int v = get_edge_vertex(e); + if (best_distance[i] + w == best_distance[v]) + G.add_directed_edge(i, v, w); + } + } + return G; + } + + // Running time: O(m^2n) + T min_cut_max_flow(int source, int sink) { + // TODO: Implement non-destructive version? + // Ford-Fulkerson - "scaling algorithm" version + std::vector&, std::pair&>>> edge_pairs(this->N, std::vector&, std::pair&>>()); + T threshold = 0; + for (size_t v = this->min_index; v < this->N; v++) { + for (auto& e : this->adj[v]) { + if (get_edge_weight(e) == 0) continue; + threshold = threshold > get_edge_weight(e) ? threshold : get_edge_weight(e); // max(threshold, get_edge_weight(e)); + int u = get_edge_vertex(e); + this->adj[u].push_back(construct_edge(v, 0)); + edge_pairs[v].push_back({e, this->adj[u][this->adj[u].size()-1]}); + edge_pairs[u].push_back({this->adj[u][this->adj[u].size()-1], e}); + } + } + + std::vector visited(this->N, false); + std::vector&, std::pair&>> path; + while (true) { + bool res = min_cut_max_flow_dfs(edge_pairs, path, visited, source, sink, threshold); + if (res == EXIT_SUCCESS) { + T path_max_flow = std::numeric_limits::max(); + for (auto e : path) + path_max_flow = path_max_flow < get_edge_weight(e.first) ? path_max_flow : get_edge_weight(e.first); + // min(path_max_flow, get_edge_weight(e.first)); + for (auto e : path) { + e.first = construct_edge(get_edge_vertex(e.first), get_edge_weight(e.first)-threshold); + e.second = construct_edge(get_edge_vertex(e.second), get_edge_weight(e.second)+threshold); + } + } else { + if (threshold == 1) + break; // Done! + threshold /= 2; + } + std::fill(visited.begin(), visited.end(), false); + path.clear(); + } + + T max_flow = 0; + for (auto e : this->adj[sink]) { + max_flow += get_edge_weight(e); + } + + return max_flow; + } +}; + +template +class BaseGraph { + std::vector top_sort; + int contains_cycles = 0; // 0 = unknown, 1 = yes, 2 = no + bool contains_negative_edge_weight = false; + + virtual int get_edge_vertex(EDGE) = 0; + virtual T get_edge_weight(EDGE) = 0; + virtual EDGE construct_edge(int vertex, T w) = 0; + + bool topological_sort_dfs(std::vector& status, int v, std::vector& top_sort) { + if (status[v] == 1) + return EXIT_FAILURE; + if (status[v] == 0) { + status[v] = 1; + for (auto e : adj[v]) { + bool res = topological_sort_dfs(status, get_edge_vertex(e), top_sort); + if (res == EXIT_FAILURE) + return EXIT_FAILURE; + } + status[v] = 2; + top_sort.push_back(v); + } + return EXIT_SUCCESS; + } + + void do_topological_sort() { + std::vector status(N, 0); + std::vector top_sort = std::vector(); + for (size_t i = min_index; i < N; i++) { + bool res = topological_sort_dfs(status, i, top_sort); + if (res == EXIT_FAILURE) { + contains_cycles = 1; + return; + } + } + + contains_cycles = 2; + std::reverse(top_sort.begin(), top_sort.end()); + this->top_sort = top_sort; + } + + public: + size_t N; + size_t min_index; + std::vector> adj; + + BaseGraph(size_t N, size_t min_index) { + N += min_index; + this->N = N; + this->min_index = min_index; + adj = std::vector>(N, std::vector()); + } + + void add_directed_edge(int from, int to, T w = 1) { + adj[from].push_back(construct_edge(to, w)); + contains_cycles = 0; + if (w < 0) + contains_negative_edge_weight = true; + } + + void add_undirected_edge(size_t a, size_t b, T w = 1) { + adj[a].push_back(construct_edge(b, w)); + adj[b].push_back(construct_edge(a, w)); + contains_cycles = 0; + if (w < 0) + contains_negative_edge_weight = true; + } + + std::vector get(int v) { + return adj[v]; + } + + std::vector topological_sort() { + if (contains_cycles != 2) + std::cerr << "Check for cycles first!" << std::endl; + return top_sort; + } + + bool has_cycles() { + if (contains_cycles == 0) + do_topological_sort(); + return contains_cycles == 1; + } + + std::vector count_paths(int from) { + if (contains_cycles != 2) + std::cerr << "Check for cycles first!" << std::endl; + std::vector paths(N, 0); + for (auto v : top_sort) { + T p = 0; + if (v == from) p++; + for (auto e : adj[v]) + p += paths[get_edge_vertex(e)]; + paths[v] = p; + } + return paths; + } + + std::vector dijkstra(int from) { + if (contains_negative_edge_weight) + std::cerr << "Dijkstra only works if the graph doesn't contain any negative edge weights" << std::endl; + std::vector distance(N, std::numeric_limits::max()); + distance[from] = 0; + std::vector processed(N, false); + std::priority_queue> q; + q.push({0, from}); + while (!q.empty()) { + int v = q.top().second; q.pop(); + if (processed[v]) continue; + processed[v] = true; + for (auto e : adj[v]) { + int u = get_edge_vertex(e); + T w = get_edge_weight(e); + if (distance[v] + w < distance[u]) { + distance[u] = distance[v] + w; + q.push({-distance[u], u}); + } + } + } + return distance; + } +}; + + + +using namespace std; + +int main() { + // TODO: SEGFAULT + // WeightedGraph G(6, 1); + // G.add_directed_edge(1, 2, 5); + // G.add_directed_edge(1, 4, 4); + // G.add_directed_edge(4, 2, 3); + // G.add_directed_edge(2, 3, 6); + // G.add_directed_edge(4, 5, 1); + // G.add_directed_edge(3, 5, 8); + // G.add_directed_edge(3, 6, 5); + // G.add_directed_edge(5, 6, 2); + + // cout << "foo" << endl; + // cout << G.min_cut_max_flow(1, 6) << endl; + + // // Works! (Probably) + // WeightedGraph G(6, 1); + // G.add_directed_edge(1, 2, 5); + // G.add_directed_edge(4, 1, 4); + // G.add_directed_edge(4, 5, 4); + // G.add_directed_edge(5, 2, 4); + // G.add_directed_edge(5, 3, 4); + // G.add_directed_edge(2, 3, 4); + // G.add_directed_edge(3, 6, 4); + + // cout << "foo" << endl; + // bool cycles = G.has_cycles(); + // cout << "Has cycles: " << cycles << endl; + // vector top = G.topological_sort(); + // for (auto i : top) + // cout << i << " "; + // cout << endl; + + // // Works! (Probably) + // WeightedGraph G(6, 1); + // G.add_directed_edge(1, 2, 5); + // G.add_directed_edge(1, 4, 4); + // G.add_directed_edge(5, 1, 4); + // G.add_directed_edge(4, 5, 4); + // G.add_directed_edge(5, 2, 4); + // G.add_directed_edge(5, 3, 4); + // G.add_directed_edge(2, 3, 4); + // G.add_directed_edge(3, 6, 4); + + // cout << "foo" << endl; + // bool cycles = G.has_cycles(); + // cout << "Has cycles: " << cycles << endl; + + // // Works! (Probably) + // Graph G(6, 1); + // G.add_directed_edge(1, 2); + // G.add_directed_edge(4, 1); + // G.add_directed_edge(4, 5); + // G.add_directed_edge(5, 2); + // G.add_directed_edge(5, 3); + // G.add_directed_edge(2, 3); + // G.add_directed_edge(3, 6); + + // cout << "foo" << endl; + // bool cycles = G.has_cycles(); + // cout << "Has cycles: " << cycles << endl; + // vector top = G.topological_sort(); + // for (auto i : top) + // cout << i << " "; + // cout << endl; + + // Works! (Probably) + WeightedGraph G(6, 1); + G.add_directed_edge(1, 2, 5); + G.add_directed_edge(4, 1, 4); + G.add_directed_edge(4, 5, 4); + G.add_directed_edge(5, 2, 4); + G.add_directed_edge(5, 3, 4); + G.add_directed_edge(2, 3, 4); + G.add_directed_edge(3, 6, 4); + + cout << "foo" << endl; + bool cycles = G.has_cycles(); + cout << "Has cycles: " << cycles << endl; + vector dist = G.dijkstra(1); + for (int i = 1; i <= 6; i++) + cout << i << " " << dist[i] << endl; + + return EXIT_SUCCESS; +} diff --git a/CPP/hpc/dmalloc_2d.c.snip b/CPP/hpc/dmalloc_2d.c.snip new file mode 100644 index 0000000..71027e0 --- /dev/null +++ b/CPP/hpc/dmalloc_2d.c.snip @@ -0,0 +1,25 @@ +#include + +double** dmalloc_2d(int m, int n); +void dfree_2d(double **A); + +// allocate a double-precision m x n matrix +double** dmalloc_2d(int m, int n) { + if (m <= 0 || n <= 0) return NULL; + double **A = malloc(m * sizeof(double *)); + if (A == NULL) return NULL; + A[0] = malloc(m*n*sizeof(double)); + if (A[0] == NULL) { + free(A); + return NULL; + } + for (int i = 1; i < m; i++) + A[i] = A[0] + i * n; + return A; +} + +// de-allocating memory, allocated with dmalloc_2d +void dfree_2d(double **A) { + free(A[0]); + free(A); +} diff --git a/CPP/hpc/include_cblas.c.snip b/CPP/hpc/include_cblas.c.snip new file mode 100644 index 0000000..1b3612a --- /dev/null +++ b/CPP/hpc/include_cblas.c.snip @@ -0,0 +1,6 @@ +#include +#if defined(__MACH__) && defined(__APPLE__) +#include +#else +#include +#endif diff --git a/CPP/range_queries/SegmentTree.cpp.snip b/CPP/range_queries/SegmentTree.cpp.snip new file mode 100644 index 0000000..960d27a --- /dev/null +++ b/CPP/range_queries/SegmentTree.cpp.snip @@ -0,0 +1,142 @@ +#define NDEBUG + +#include +#include +#include +#include + +template class SegmentTree; +template class SumSegmentTree; +template class MinSegmentTree; +template class MaxSegmentTree; +template class DifferenceSegmentTree; + +template +class SumSegmentTree : public SegmentTree { + virtual T cmp (T a, T b) override { + return a + b; + } + + public: + SumSegmentTree(size_t N) : SegmentTree(N, 0) {}; +}; + +template +class MinSegmentTree : public SegmentTree { + virtual T cmp (T a, T b) override { + return (a < b) ? a : b; + } + + public: + MinSegmentTree(size_t N) : SegmentTree(N, std::numeric_limits::max()) {}; +}; + +template +class MaxSegmentTree : public SegmentTree { + virtual T cmp (T a, T b) override { + return (a > b) ? a : b; + } + + public: + MaxSegmentTree(size_t N) : SegmentTree(N, std::numeric_limits::min()) {}; +}; + +template +class DifferenceSegmentTree : public SegmentTree { + virtual T cmp (T a, T b) override { + return a+b; + } + + public: + virtual void add(size_t i, T val) override { + this->set(i, this->get(i) + val); + if (i != this->N-1) + this->set(i+1, this->get(i+1) - val); + } + + void add_range(size_t i, size_t j, T val) { + this->set(i, this->get(i) + val); + if (j+1 != this->N) + this->set(j+1, this->get(j+1)-val); + } + + DifferenceSegmentTree(size_t N) : SegmentTree(N, 0) {}; +}; + +template +class SegmentTree { + const T unit; + virtual T cmp (T a, T b) = 0; + std::vector arr; + + public: + size_t N; + + void print() { + size_t newline = 2; + for (size_t i = 1; i < 2*N; i++) { + std::cout << arr[i] << " "; + if (i == newline-1) { + std::cout << std::endl; + newline *= 2; + } + } + } + + SegmentTree(size_t N, T unit) : unit(unit) { + this->N = N; + // Initialize the array to the size of the smallest power of two greater than N + size_t exp = 0; + while (N != 0) { + N = N >> 1; + exp++; + } + if ((size_t)(1 << (exp-1)) == this->N) + arr = std::vector(this->N*2, unit); + else + arr = std::vector(1 << (exp+1), unit); + } + + T get(size_t i) { +#ifndef NDEBUG + if (i >= N) + std::cerr << "Tried accessing index " << i << " out of " << N-1 << " (remember, 0-indexing)" << std::endl; +#endif + return arr[i+N]; + } + /* T operator[](size_t i) { get(i); }; */ + + virtual void set(size_t i, T val) { + update_field(i, val); + } + + void update_field(size_t i, T val) { +#ifndef NDEBUG + if (i >= N) + std::cerr << "Tried updating index " << i << " out of " << N-1 << " (remember, 0-indexing)" << std::endl; +#endif + i += N; // Put the index at the leaf nodes/original array + arr[i] = val; + for (i /= 2; i >= 1; i /= 2) + arr[i] = cmp(arr[i*2], arr[i*2+1]); + } + + virtual void add(size_t i, T val) { + set(i, val + get(i)); + } + + T query(size_t a, size_t b) { +#ifndef NDEBUG + if (a > N || b > N || a > b) + std::cerr << "Tried querying the range: [" << a << ", " << b << "]" << " of max index " << N-1 << std::endl; +#endif + a += N; b += N; + size_t val = unit; + while (a <= b) { + if (a % 2 == 1) val = cmp(val, arr[a++]); + if (b % 2 == 0) val = cmp(val, arr[b--]); + a /= 2; b /= 2; + } + return val; + } +}; diff --git a/CPP/utility/prime_sieve.cpp.snip b/CPP/utility/prime_sieve.cpp.snip new file mode 100644 index 0000000..ca65eee --- /dev/null +++ b/CPP/utility/prime_sieve.cpp.snip @@ -0,0 +1,12 @@ +vector prime_sieve(int n) { + vector is_prime(n+1, true); + is_prime[0] = is_prime[1] = false; + vector primes; + for (int i = 2; i <= n; i++) { + if (!is_prime[i]) continue; + primes.push_back(i); + for (int j = i; j <= n; j += i) + is_prime[j] = false; + } + return primes; +} diff --git a/HTML.html.snip b/HTML.html.snip new file mode 100644 index 0000000..a6d05e2 --- /dev/null +++ b/HTML.html.snip @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Markdown.md.snip b/Markdown.md.snip new file mode 100644 index 0000000..bd2a481 --- /dev/null +++ b/Markdown.md.snip @@ -0,0 +1,18 @@ + + +
+ + + + + +# Table of Contents + + + + + + +
diff --git a/install_configfiles.sh b/install_configfiles.sh new file mode 100644 index 0000000..8e04bef --- /dev/null +++ b/install_configfiles.sh @@ -0,0 +1,4 @@ +#!/bin/bash +mkdir -p ~/.config/nvim; +rm -df ~/.config/nvim/snippets; +ln -s ~/Nextcloud/configfiles/vim/snippets ~/.config/nvim/snippets; diff --git a/julia_OR.jl.snip b/julia_OR.jl.snip new file mode 100644 index 0000000..32826ee --- /dev/null +++ b/julia_OR.jl.snip @@ -0,0 +1,29 @@ +using JuMP, GLPK + +profit = [5, 3, 2, 7, 4] +weight = [2, 8, 4, 2, 5] +capacity = 10 + +model = Model(GLPK.Optimizer) + +n = 5 +@variable(model, x[1:n], Bin) # Binary +@variable(model, y[1:n], Int) # Integer +@variable(model, z[1:n]) # Continuous + +@objective(model, Max, sum(profit[i]*x[i] for i=1:n)) +@constraint(model, sum(weight[i]*x[i] for i=1:n) <= capacity) +@constraint(model, [i=1:n], x[i] <= 1) # unnecessary, just to include this syntax in the example + +JuMP.optimize!(model) + +if termination_status(model) == MOI.OPTIMAL + println("Objective is: ", JuMP.objective_value(model)) + print("Solution is:") + for i=1:n + print(" ", JuMP.value(x[i])) + end + println() +else + println("Optimise was not successful. Return code ", termination_status(model)) +end diff --git a/latex.tex.snip b/latex.tex.snip new file mode 100644 index 0000000..42d6127 --- /dev/null +++ b/latex.tex.snip @@ -0,0 +1,17 @@ +\documentclass[11pt]{article} +\usepackage{../../../Texpreambles/JRPreamble} +\DTMsavedate{mydate}{2022-9-5}% chktex 8 + +\usepackage{listings} + +\begin{document} +\selectlanguage{british} + +\begin{center} + \Huge My Course: Assignment 1 \\ + \Large Jonas Ryssel \\ + \Large s184009 \\ + \Large \DTMusedate{mydate} +\end{center} + +\end{document} diff --git a/rust/unit_test.rs.snip b/rust/unit_test.rs.snip new file mode 100644 index 0000000..e21624a --- /dev/null +++ b/rust/unit_test.rs.snip @@ -0,0 +1,9 @@ +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn my_test() { + assert_eq!(add(1, 2), 3); + } +}