From 8d11c6c8213f46f0fa19826917c255edd5d43cb1 Mon Sep 17 00:00:00 2001 From: mzuenni Date: Sun, 28 Jul 2024 22:54:40 +0200 Subject: Test (#4) * update * moved content in subdir * rename file * add test setup * add test setup * add github action * automaticly test all cpp files * timeout after 10s * setulimit and dont zero memory * test build pdf * install latexmk * update * update * ngerman * fonts * removed old code * add first test * added tests * test in sorted order * more tests * simplified test * more tests * fix suffix tree * fixes and improvements * done ust lst directly * fix swap * add links to pdf * fix constants * add primorial * add comment * various improvements * more tests * added missing stuf * more tests * fix tests * more tests * more tests * more tests * fix recursion? * test trie * more tests * only use python temporarily for listings * only use python temporarily for listings * more tests * fix longestCommonSubstring * more tests * more tests * made code more similiar * fix? * more tests * more tests * more tests * add ahoCorasick test + limit 4GB stack size * more tests * fix test * add additional test * more tests * more tests * fix? * better fix * fix virtual tree * more tests * more tests * recursive closest pair * more tests * decrease limit * new tests * more tests * fix name * more tests * add test * new test * more tests * more tests * more tests * more tests * new test and content * new code * new code * larger tests * fix and test * new test * new test * update pdf * remove comments * new test * more tests * more testcases * more tests * increased limit * more tests * more tests * more tests * new tests * more tests * shortened code * new test * add basic tests for bigint * more tests * removed old files * new test * ignore some files * more auto more ccw * fix test * more tests * fix * new tests * more tests * more tests * stronger test * actually verify delaunay... * more tests * fix header * more tests * run tests parallel? * test parralel? * add --missing * separate workflows * test * is the pdf checked? * separate workflows * fix workflow * more workflows --------- Co-authored-by: Yidi --- content/other/bitOps.cpp | 18 +++ content/other/compiletime.cpp | 7 + content/other/divideAndConquer.cpp | 27 ++++ content/other/fastIO.cpp | 24 +++ content/other/josephus2.cpp | 8 + content/other/josephusK.cpp | 5 + content/other/knuth.cpp | 15 ++ content/other/other.tex | 312 +++++++++++++++++++++++++++++++++++++ content/other/pbs.cpp | 19 +++ content/other/pragmas.cpp | 6 + content/other/sos.cpp | 6 + content/other/split.cpp | 10 ++ content/other/stress.sh | 7 + content/other/stuff.cpp | 29 ++++ content/other/timed.cpp | 3 + 15 files changed, 496 insertions(+) create mode 100644 content/other/bitOps.cpp create mode 100644 content/other/compiletime.cpp create mode 100644 content/other/divideAndConquer.cpp create mode 100644 content/other/fastIO.cpp create mode 100644 content/other/josephus2.cpp create mode 100644 content/other/josephusK.cpp create mode 100644 content/other/knuth.cpp create mode 100644 content/other/other.tex create mode 100644 content/other/pbs.cpp create mode 100644 content/other/pragmas.cpp create mode 100644 content/other/sos.cpp create mode 100644 content/other/split.cpp create mode 100644 content/other/stress.sh create mode 100644 content/other/stuff.cpp create mode 100644 content/other/timed.cpp (limited to 'content/other') diff --git a/content/other/bitOps.cpp b/content/other/bitOps.cpp new file mode 100644 index 0000000..8079305 --- /dev/null +++ b/content/other/bitOps.cpp @@ -0,0 +1,18 @@ +// Iteriert über alle Teilmengen einer Bitmaske +// (außer der leeren Menge). +for (int subset = bitmask; subset > 0; + subset = (subset - 1) & bitmask) + +// Zählt Anzahl der gesetzten Bits. +int numberOfSetBits(int i) { + i = i - ((i >> 1) & 0x5555'5555); + i = (i & 0x3333'3333) + ((i >> 2) & 0x3333'3333); + return (((i + (i >> 4)) & 0x0F0F'0F0F) * 0x0101'0101) >> 24; +} + +// Nächste Permutation in Bitmaske +// (z.B. 00111 => 01011 => 01101 => ...) +ll nextPerm(ll v) { + ll t = v | (v - 1); + return (t+1) | (((~t & -~t) - 1) >> (__builtin_ctzll(v) + 1)); +} diff --git a/content/other/compiletime.cpp b/content/other/compiletime.cpp new file mode 100644 index 0000000..b71f83b --- /dev/null +++ b/content/other/compiletime.cpp @@ -0,0 +1,7 @@ +template +struct Table { + int data[N]; + constexpr Table() : data {} { + for (int i = 0; i < N; i++) data[i] = i; +}}; +constexpr Table<100'000> precalculated; diff --git a/content/other/divideAndConquer.cpp b/content/other/divideAndConquer.cpp new file mode 100644 index 0000000..830dc7f --- /dev/null +++ b/content/other/divideAndConquer.cpp @@ -0,0 +1,27 @@ +vector> dp; +vector> C; + +void rec(int i, int j0, int j1, int m0, int m1) { + if (j1 < j0) return; + int jmid = (j0 + j1) / 2; + + dp[i][jmid] = inf; + int bestk = m0; + for (int k = m0; k < min(jmid, m1 + 1); ++k) { + if (dp[i - 1][k] + C[k + 1][jmid] < dp[i][jmid]) { + dp[i][jmid] = dp[i - 1][k] + C[k + 1][jmid]; + bestk = k; + }} + + rec(i, j0, jmid - 1, m0, bestk); + rec(i, jmid + 1, j1, bestk, m1); +} + +ll calc(int n, int m) { + dp = vector>(m, vector(n, inf)); + for (int i = 0; i < n; i++) dp[0][i] = C[0][i]; + for (int i = 1; i < m; i++) { + rec(i, 0, n - 1, 0, n - 1); + } + return dp[m - 1][n - 1]; +} diff --git a/content/other/fastIO.cpp b/content/other/fastIO.cpp new file mode 100644 index 0000000..9badcc7 --- /dev/null +++ b/content/other/fastIO.cpp @@ -0,0 +1,24 @@ +void fastscan(int& number) { + bool negative = false; + int c; + number = 0; + c = getchar(); + while(c != '-' && (c < '0' || c > '9')) c = getchar(); + if (c == '-') negative = true, c = getchar(); + for (; c >= '0' && c <= '9'; c = getchar()) number = number * 10 + c - '0'; + if (negative) number *= -1; +} + +void printPositive(int n) { + if (n == 0) return; + printPositive(n / 10); + putchar(n % 10 + '0'); +} + +void fastprint(int n) { + if(n == 0) {putchar('0'); return;} + if (n < 0) { + putchar('-'); + printPositive(-n); + } else printPositive(n); +} diff --git a/content/other/josephus2.cpp b/content/other/josephus2.cpp new file mode 100644 index 0000000..5086e13 --- /dev/null +++ b/content/other/josephus2.cpp @@ -0,0 +1,8 @@ +int rotateLeft(int n) { // Der letzte Überlebende, 1-basiert. + for (int i = 31; i >= 0; i--) { + if (n & (1 << i)) { + n &= ~(1 << i); + break; + }} + n <<= 1; n++; return n; +} diff --git a/content/other/josephusK.cpp b/content/other/josephusK.cpp new file mode 100644 index 0000000..5025f89 --- /dev/null +++ b/content/other/josephusK.cpp @@ -0,0 +1,5 @@ +// Der letzte Überlebende, 0-basiert. +int josephus(int n, int k) { + if (n == 1) return 0; + return (josephus(n - 1, k) + k) % n; +} diff --git a/content/other/knuth.cpp b/content/other/knuth.cpp new file mode 100644 index 0000000..1d513c8 --- /dev/null +++ b/content/other/knuth.cpp @@ -0,0 +1,15 @@ +ll calc(int n, int m, const vector>& C) { + vector> dp(m, vector(n, inf)); + vector> opt(m, vector(n + 1, n - 1)); + + for (int i = 0; i < n; i++) dp[0][i] = C[0][i]; + for (int i = 1; i < m; i++) { + for (int j = n - 1; j >= 0; --j) { + opt[i][j] = i == 1 ? 0 : opt[i - 1][j]; + for (int k = opt[i][j]; k <= min(opt[i][j+1], j-1); k++) { + if (dp[i][j] <= dp[i - 1][k] + C[k + 1][j]) continue; + dp[i][j] = dp[i - 1][k] + C[k + 1][j]; + opt[i][j] = k; + }}} + return dp[m - 1][n - 1]; +} diff --git a/content/other/other.tex b/content/other/other.tex new file mode 100644 index 0000000..b47893f --- /dev/null +++ b/content/other/other.tex @@ -0,0 +1,312 @@ +\section{Sonstiges} + +\begin{algorithm}{Compiletime} + \begin{itemize} + \item überprüfen ob Compilezeit Berechnungen erlaubt sind! + \item braucht \code{c++14} oder höher! + \end{itemize} + \sourcecode{other/compiletime.cpp} +\end{algorithm} + +\begin{algorithm}{Timed} + Kann benutzt werden um randomisierte Algorithmen so lange wie möglich laufen zu lassen. + \sourcecode{other/timed.cpp} +\end{algorithm} + +\begin{algorithm}{Bit Operations} + \begin{expandtable} + \begin{tabularx}{\linewidth}{|Ll|} + \hline + Bit an Position j lesen & \code{(x & (1 << j)) != 0} \\ + Bit an Position j setzten & \code{x |= (1 << j)} \\ + Bit an Position j löschen & \code{x &= ~(1 << j)} \\ + Bit an Position j flippen & \code{x ^= (1 << j)} \\ + Anzahl an führenden nullen ($x \neq 0$) & \code{__builtin_clzll(x)} \\ + Anzahl an schließenden nullen ($x \neq 0$) & \code{__builtin_ctzll(x)} \\ + Anzahl an \code{1} bits & \code{__builtin_popcountll(x)} \\ + $i$-te Zahl eines Graycodes & \code{i ^ (i >> 1)} \\ + \hline + \end{tabularx}\\ + \end{expandtable} + \sourcecode{other/bitOps.cpp} +\end{algorithm} + +\begin{algorithm}{Overflow-sichere arithmetische Operationen} + Gibt zurück, ob es einen Overflow gab. Wenn nicht, enthält \code{c} das Ergebnis. + \begin{expandtable} + \begin{tabularx}{\linewidth}{|lR|} + \hline + Addition & \code{__builtin_saddll_overflow(a, b, &c)} \\ + Subtraktion & \code{__builtin_ssubll_overflow(a, b, &c)} \\ + Multiplikation & \code{__builtin_smulll_overflow(a, b, &c)} \\ + \hline + \end{tabularx} + \end{expandtable} +\end{algorithm} + +\begin{algorithm}{Pragmas} + \sourcecode{other/pragmas.cpp} +\end{algorithm} + +\begin{algorithm}{DP Optimizations} + Aufgabe: Partitioniere Array in genau $m$ zusammenhängende Teile mit minimalen Kosten: + $dp[i][j] = \min_{kn>0,~k>0$ und $m\not\equiv n \bmod 2$ dann beschreibt diese Formel alle Pythagoreischen Tripel eindeutig: + \[k~\cdot~\Big(~a=m^2-n^2,\quad b=2mn,\quad c=m^2+n^2~\Big)\] + + \item \textbf{Centroids of a Tree:} + Ein \emph{Centroid} ist ein Knoten, der einen Baum in Komponenten der maximalen Größe $\frac{\abs{V}}{2}$ splitted. + Es kann $2$ Centroids geben! + + \item \textbf{Centroid Decomposition:} + Wähle zufälligen Knoten und mache DFS. + Verschiebe ausgewählten Knoten in Richtung des tiefsten Teilbaums, bis Centroid gefunden. Entferne Knoten, mache rekursiv in Teilbäumen weiter. Laufzeit:~\runtime{\abs{V} \cdot \log(\abs{V})}. + \item \textbf{Gregorian Calendar:} Der Anfangstag des Jahres ist alle $400$ Jahre gleich. + + \item \textbf{Pivotsuche und Rekursion auf linkem und rechtem Teilarray:} + Suche gleichzeitig von links und rechts nach Pivot, um Worst Case von + $\runtime{n^2}$ zu $\runtime{n\log n}$ zu verbessern. + + \item \textbf{\textsc{Mo}'s Algorithm:} + SQRT-Decomposition auf $n$ Intervall Queries $[l,r]$. + Gruppiere Queries in $\sqrt{n}$ Blöcke nach linker Grenze $l$. + Sortiere nach Block und bei gleichem Block nach rechter Grenze $r$. + Beantworte Queries offline durch schrittweise Vergrößern/Verkleinern des aktuellen Intervalls. + Laufzeit:~\runtime{n\cdot\sqrt{n}}. + (Anzahl der Blöcke als Konstante in Code schreiben.) + + \item \textbf{SQRT Techniques:} + \begin{itemize} + \item Aufteilen in \emph{leichte} (wert $\leq\sqrt{x}$) und \emph{schwere} (höchsten $\sqrt{x}$ viele) Objekte. + \item Datenstruktur in Blöcke fester Größe (z.b. 256 oder 512) aufteilen. + \item Datenstruktur nach fester Anzahl Updates komplett neu bauen. + \item Wenn die Summe über $x_i$ durch $X$ beschränkt ist, dann gibt es nur $\sqrt{2X}$ verschiedene Werte von $x_i$ (z.b. Längen von Strings). + \item Wenn $w\cdot h$ durch $X$ beschränkt ist, dann ist $\min(w,h)\leq\sqrt{X}$. + \end{itemize} + + \item \textbf{Partition:} + Gegeben Gewichte $w_0+w_1+\cdots+w_k=W$, existiert eine Teilmenge mit Gewicht $x$? + Drei gleiche Gewichte $w$ können zu $w$ und $2w$ kombiniert werden ohne die Lösung zu ändern $\Rightarrow$ nur $2\sqrt{W}$ unterschiedliche Gewichte. + Mit bitsets daher selbst für $10^5$ lösbar. +\end{itemize} + +\subsection{Tipps \& Tricks} + +\begin{itemize} + \item \textbf{Run Time Error:} + \begin{itemize} + \item Stack Overflow? Evtl. rekursive Tiefensuche auf langem Pfad? + \item Array-Grenzen überprüfen. Indizierung bei $0$ oder bei $1$ beginnen? + \item Abbruchbedingung bei Rekursion? + \item Evtl. Memory Limit Exceeded? Mit \code{/usr/bin/time -v} erhält man den maximalen Speicherverbrauch bei der Ausführung (Maximum resident set size). + \end{itemize} + + \item \textbf{Strings:} + \begin{itemize} + \item Soll \codeSafe{"aa"} kleiner als \codeSafe{"z"} sein oder nicht? + \item bit \code{0x20} beeinflusst Groß-/Kleinschreibung. + \end{itemize} + + \item \textbf{Zeilenbasierte Eingabe}: + \begin{itemize} + \item \code{getline(cin, str)} liest Zeile ein. + \item Wenn vorher \code{cin >> ...} benutzt, lese letztes \code{\\n} mit \code{getline(cin, x)}. + \end{itemize} + + \item \textbf{Gleitkommazahlen:} + \begin{itemize} + \item \code{NaN}? Evtl. ungültige Werte für mathematische Funktionen, z.B. \mbox{\code{acos(1.00000000000001)}}? + \item Falsches Runden bei negativen Zahlen? Abschneiden $\neq$ Abrunden! + \item genügend Präzision oder Output in wissenschaftlicher Notation (\code{1e-25})? + \item Kann \code{-0.000} ausgegeben werden? + \end{itemize} + + \item \textbf{Wrong Answer:} + \begin{itemize} + \item Lies Aufgabe erneut. Sorgfältig! + \item Mehrere Testfälle in einer Datei? Probiere gleichen Testcase mehrfach hintereinander. + \item Integer Overflow? Teste maximale Eingabegrößen und mache Überschlagsrechnung. + \item Ausgabeformat im 'unmöglich'-Fall überprüfen. + \item Ist das Ergebnis modulo einem Wert? + \item Integer Division rundet zur $0$ $\neq$ abrunden. + \item Eingabegrößen überprüfen. Sonderfälle ausprobieren. + \begin{itemize} + \item $n = 0$, $n = -1$, $n = 1$, $n = 2^{31}-1$, $n = -2^{31}$ + \item $n$ gerade/ungerade + \item Graph ist leer/enthält nur einen Knoten. + \item Liste ist leer/enthält nur ein Element. + \item Graph ist Multigraph (enthält Schleifen/Mehrfachkanten). + \item Sind Kanten gerichtet/ungerichtet? + \item Kolineare Punkte existieren. + \item Polygon ist konkav/selbstschneidend. + \end{itemize} + \item Bei DP/Rekursion: Stimmt Basisfall? + \item Unsicher bei benutzten STL-Funktionen? + \end{itemize} +\end{itemize} diff --git a/content/other/pbs.cpp b/content/other/pbs.cpp new file mode 100644 index 0000000..7cb60e5 --- /dev/null +++ b/content/other/pbs.cpp @@ -0,0 +1,19 @@ +// Q = # of queries, bucket sort is sometimes faster +vector low(Q, 0), high(Q, MAX_OPERATIONS); +while (true) { + vector> focus; + for (int i = 0; i < Q; i++) if (low[i] < high[i]) { + focus.emplace_back((low[i] + high[i]) / 2, i); + } + if (focus.empty()) break; + sort(all(focus)); + + // reset simulation + for (int step = 0; auto [mid, i] : focus) { + while (step <= mid) { + // simulation step + step++; + } + if (/* requirement already fulfilled */) high[i] = mid; + else low[i] = mid + 1; +}} // answer in low (and high) diff --git a/content/other/pragmas.cpp b/content/other/pragmas.cpp new file mode 100644 index 0000000..a39c850 --- /dev/null +++ b/content/other/pragmas.cpp @@ -0,0 +1,6 @@ +#pragma GCC optimize("Ofast") +#pragma GCC optimize ("unroll-loops") +#pragma GCC target("sse,sse2,sse3,ssse3,sse4," + "popcnt,abm,mmx,avx,tune=native") +#pragma GCC target("fpmath=sse,sse2") // no excess precision +#pragma GCC target("fpmath=387") // force excess precision diff --git a/content/other/sos.cpp b/content/other/sos.cpp new file mode 100644 index 0000000..01bc44c --- /dev/null +++ b/content/other/sos.cpp @@ -0,0 +1,6 @@ +vector res(in); +for (int i = 1; i < sz(res); i *= 2) { + for (int mask = 0; mask < sz(res); mask++){ + if (mask & i) { + res[mask] += res[mask ^ i]; +}}} diff --git a/content/other/split.cpp b/content/other/split.cpp new file mode 100644 index 0000000..5519f60 --- /dev/null +++ b/content/other/split.cpp @@ -0,0 +1,10 @@ +// Zerlegt s anhand aller Zeichen in delim (verändert s). +vector split(string& s, string delim) { + vector result; char *token; + token = strtok(s.data(), delim.c_str()); + while (token != nullptr) { + result.emplace_back(token); + token = strtok(nullptr, delim.c_str()); + } + return result; +} diff --git a/content/other/stress.sh b/content/other/stress.sh new file mode 100644 index 0000000..d264c2a --- /dev/null +++ b/content/other/stress.sh @@ -0,0 +1,7 @@ +for i in {1..1000}; do + printf "\r$i" + python3 gen.py > input # generate test with gen.py + ./a.out < input > out # execute ./a.out + ./b.out < input > out2 # execute ./b.out + diff out out2 || break +done diff --git a/content/other/stuff.cpp b/content/other/stuff.cpp new file mode 100644 index 0000000..41543ad --- /dev/null +++ b/content/other/stuff.cpp @@ -0,0 +1,29 @@ +// Alles-Header. +#include + +// Setzt deutsche Tastaturlayout / toggle mit alt + space +setxkbmap de +setxkbmap de,us -option grp:alt_space_toggle + +// Schnelle Ein-/Ausgabe mit cin/cout. +cin.tie(nullptr)->ios::sync_with_stdio(false); + +// Set mit eigener Sortierfunktion. +set set1(comp); + +// STL-Debugging, Compiler flags. +-D_GLIBCXX_DEBUG +#define _GLIBCXX_DEBUG + +// 128-Bit Integer/Float. Muss zum Einlesen/Ausgeben +// in einen int oder long long gecastet werden. +__int128, __float128 + +// float mit Decimaldarstellung +#include +std::decimal::decimal128 + +// 1e18 < INF < Max_Value / 2 +constexpr ll INF = 0x3FFF'FFFF'FFFF'FFFFll; +// 1e9 < INF < Max_Value / 2 +constexpr int INF = 0x3FFF'FFFF; diff --git a/content/other/timed.cpp b/content/other/timed.cpp new file mode 100644 index 0000000..b3ed4ef --- /dev/null +++ b/content/other/timed.cpp @@ -0,0 +1,3 @@ +int times = clock(); +//run for 900ms +while (1000*(clock()-times)/CLOCKS_PER_SEC < 900) {...} -- cgit v1.2.3