aboutsummaryrefslogtreecommitdiff
path: root/C++
diff options
context:
space:
mode:
authorSyndamia <kamen.d.mladenov@protonmail.com>2021-11-12 09:23:19 +0200
committerSyndamia <kamen.d.mladenov@protonmail.com>2021-11-12 09:23:19 +0200
commitdbaf69f0e0ede46cbf5765cb6ca9500fcd7a3ea7 (patch)
tree42890f66de25479419a2be48af695f79be7c155d /C++
parentda0cd9df96b09425416869e819af9633866374ab (diff)
downloadalgorithms-dbaf69f0e0ede46cbf5765cb6ca9500fcd7a3ea7.tar
algorithms-dbaf69f0e0ede46cbf5765cb6ca9500fcd7a3ea7.tar.gz
algorithms-dbaf69f0e0ede46cbf5765cb6ca9500fcd7a3ea7.zip
Divided C and C++ files into seperate folders
Diffstat (limited to 'C++')
-rw-r--r--C++/FindSpiralNumber.cpp179
-rw-r--r--C++/FindSpiralNumberCoord.cpp147
-rw-r--r--C++/LeibnizPI.cpp26
-rw-r--r--C++/QuadraticEquationGrapher.cpp63
-rw-r--r--C++/README.md4
5 files changed, 419 insertions, 0 deletions
diff --git a/C++/FindSpiralNumber.cpp b/C++/FindSpiralNumber.cpp
new file mode 100644
index 0000000..78e1681
--- /dev/null
+++ b/C++/FindSpiralNumber.cpp
@@ -0,0 +1,179 @@
+#include <iostream>
+
+using namespace std;
+
+int main()
+{
+ int x, y;
+ cout << "x = ";
+ cin >> x;
+ cout << "y = ";
+ cin >> y;
+
+ int n, v = max(abs(x), abs(y)), g = 8 * (v * (v + 1) / 2);
+
+ if (y == v || x == v) { // Top row or right column
+ n = g - x + y - 6 * v;
+ }
+ else { // Left column or bottom row
+ n = g + x - y - 2 * v;
+ }
+
+ printf("n = %d", n);
+
+ return 0;
+}
+
+/* --------------
+ * Task condition
+ * --------------
+ * You have a spiral of whole numbers, starting from 0, like this:
+ *
+ * 36 < 35 < 34 < 33 < 32 < 31 < 30
+ * V ^
+ * 37 16 < 15 < 14 < 13 < 12 29
+ * V V ^ ^
+ * 38 17 4 < 3 < 2 11 28
+ * V V V ^ ^ ^
+ * 39 18 5 0 > 1 10 27 ...
+ * V V V ^ ^ ^
+ * 40 19 6 > 7 > 8 > 9 26 51
+ * V V ^ ^
+ * 41 20 > 21 > 22 > 23 > 24 > 25 50
+ * V ^
+ * 42 > 43 > 44 > 45 > 46 > 47 > 48 > 49
+ *
+ * The distance between two neighbouring numbers is 1, meaning 0 is at (0;0), 1 is at (1;0), 38 is at (-3;1).
+ * You are given the coordinates of a number and you have to find the actual number.
+ *
+ * --------------------------
+ * Explanation of my solution
+ * --------------------------
+ *
+ * My solution is a very mathematical one. First, I divide the spiral into squares,
+ * depending on the offset of 0;0.
+ * Example:
+ * - Square 1 (because x and y are between -1 and 1 (one of them is always 1 or -1)):
+ * 4 < 3 < 2
+ * V ^
+ * 5 1
+ * V
+ * 6 > 7 > 8
+ *
+ * - Square 2 (because x and y are between -2 and 2 (one of them is always 2 or -2)):
+ * 16 < 15 < 14 < 13 < 12
+ * V ^
+ * 17 11
+ * V ^
+ * 18 10
+ * V ^
+ * 19 9
+ * V
+ * 20 > 21 > 22 > 23 > 24
+ *
+ * - Square 3 (because x and y are between -3 and 3 (one of them is always 3 or -3)):
+ * 36 < 35 < 34 < 33 < 32 < 31 < 30
+ * V ^
+ * 37 29
+ * V ^
+ * 38 28
+ * V ^
+ * 39 27
+ * V ^
+ * 40 26
+ * V ^
+ * 41 25
+ * V
+ * 42 > 43 > 44 > 45 > 46 > 47 > 48
+ *
+ * And so on. I call the number of the square "v".
+ * We can find it by getting the absolute value of both coordinates and get the biggest number.
+ *
+ * Then there is the biggest number in the square, the one in the bottom right corner, I call that "g".
+ * g for square 1 (v = 1) is 8, for v = 2: g = 24, for v = 3: g = 48 and so on.
+ * We can see that each g is divisble by 8, but the multiplier is slightly tricky to find.
+ * The multiplier is the sum of all whole number from 1 up until v.
+ *
+ * Example:
+ * v = 2
+ * g = 8 * (Sum of numbers from 1 to v) = 8 * (1 + 2) = 8 * 3 = 24
+ *
+ * v = 3
+ * g = 8 * (Sum of numbers from 1 to v) = 8 * (1 + 2 + 3) = 8 * 6 = 48
+ *
+ * Then, we divide the whole square into two corners. We take the diagonal from top left to bottom right, and check in which part the coordinates are.
+ * We do that because we have two formulas. In brief, what they do is tranform the coordinates into the number from which we'll subtract from g.
+ *
+ * Example:
+ * v = 3, g = 48
+ *
+ * Lets take a look at the formula for the bottom of the square. We aren't interested in g, so the important part is "x - y - 2*v".
+ * What it does is make the coordinates for x and y correspond to a number from -12 to 0.
+ * So this:
+ * 36
+ * V
+ * 37
+ * V
+ * 38
+ * V
+ * 39
+ * V
+ * 40
+ * V
+ * 41
+ * V
+ * 42 > 43 > 44 > 45 > 46 > 47 > 48
+ * Becomes:
+ * -12
+ * V
+ * -11
+ * V
+ * -10
+ * V
+ * -9
+ * V
+ * -8
+ * V
+ * -7
+ * V
+ * -6 > -5 > -4 > -3 > -2 > -1 > 0
+ *
+ * "- 2 * v" is -6, the number in the bottom left corner. Then, if we increase Y (meaning we want to go up the left column),
+ * we want the number to also decrease (make it further away from 0). We also have to account for X, because there it's always -3.
+ * So, we need them to sum up to 0 when we're on the bottom left corner, so we can just subtract Y from X. As we said,
+ * X is always -3 on the left column, so by increasing Y, we also increase the negative number.
+ *
+ * Ok, here are some example numbers:
+ * X | Y | X - Y
+ * ---|----|------
+ * -3 | -3 | 0
+ * -3 | -2 | -1
+ * -3 | 0 | -3
+ *
+ * This actually works out for us just fine when we're traversing the bottom row. There, Y is always -3, and
+ * when increasing X we want to increase our number (make it close to 0). So, X - Y become a positive number,
+ * which summed up with the negative number ("-2*v") makes the result number closer to 0, which is what we want.
+ *
+ * Here are more example numbers:
+ * X | Y | X - Y
+ * ---|----|------
+ * -3 | -3 | 0
+ * -2 | -3 | 1
+ * 0 | -3 | 3
+ *
+ * The formula for the top of the square (top row and right column) works the same , but there our corner number isn't "-2*v" but "-6*v",
+ * and we want the reverse effect: increase number (make smaller) on increasing X and decerease number on incrasing Y,
+ * so we make "X - Y" to be "Y - X"
+ *
+ * -13 < -14 < -15 < -16 < -17 < -18 < -19
+ * ^
+ * -20
+ * ^
+ * -21
+ * ^
+ * -22
+ * ^
+ * -23
+ * ^
+ * -24
+ */
diff --git a/C++/FindSpiralNumberCoord.cpp b/C++/FindSpiralNumberCoord.cpp
new file mode 100644
index 0000000..07b2071
--- /dev/null
+++ b/C++/FindSpiralNumberCoord.cpp
@@ -0,0 +1,147 @@
+#include <iostream>
+
+using namespace std;
+
+int main()
+{
+ int n, v, g, x, y;
+ cout << "n = ";
+ cin >> n;
+
+ while (g < n) {
+ v++;
+ g = 8 * (v * (v + 1) / 2);
+ }
+
+ if (n >= g - 2 * v) { // Bottom row
+ y = -v;
+ x = v - (g - n);
+ }
+ else if (n >= g - 4 * v) { // Left column
+ x = -v;
+ y = ((g - 2 * v) - n) - v;
+ }
+ else if (n >= g - 6 * v) { // Top row
+ y = v;
+ x = ((g - 4 * v) - n) - v;
+ }
+ else { // Right column
+ x = v;
+ y = v - ((g - 6 * v) - n);
+ }
+
+ printf("(%d;%d)\n", x, y);
+
+ return 0;
+}
+
+/* --------------
+ * Task condition
+ * --------------
+ * You have a spiral of whole numbers, starting from 0, like this:
+ *
+ * 36 < 35 < 34 < 33 < 32 < 31 < 30
+ * V ^
+ * 37 16 < 15 < 14 < 13 < 12 29
+ * V V ^ ^
+ * 38 17 4 < 3 < 2 11 28
+ * V V V ^ ^ ^
+ * 39 18 5 0 > 1 10 27 ...
+ * V V V ^ ^ ^
+ * 40 19 6 > 7 > 8 > 9 26 51
+ * V V ^ ^
+ * 41 20 > 21 > 22 > 23 > 24 > 25 50
+ * V ^
+ * 42 > 43 > 44 > 45 > 46 > 47 > 48 > 49
+ *
+ * You are given a number n and your goal is to find the coordinates of the number.
+ * The distance between two neighbouring numbers is 1, meaning 0 is at (0;0), 1 is at (1;0), 38 is at (-3;1).
+ *
+ * --------------------------
+ * Explanation of my solution
+ * --------------------------
+ *
+ * My solution is a very mathematical one. First, I divide the spiral into squares,
+ * depending on the offset of 0;0.
+ * Example:
+ * - Square 1 (because x and y are between -1 and 1 (one of them is always 1 or -1)):
+ * 4 < 3 < 2
+ * V ^
+ * 5 1
+ * V
+ * 6 > 7 > 8
+ *
+ * - Square 2 (because x and y are between -2 and 2 (one of them is always 2 or -2)):
+ * 16 < 15 < 14 < 13 < 12
+ * V ^
+ * 17 11
+ * V ^
+ * 18 10
+ * V ^
+ * 19 9
+ * V
+ * 20 > 21 > 22 > 23 > 24
+ *
+ * - Square 3 (because x and y are between -3 and 3 (one of them is always 3 or -3)):
+ * 36 < 35 < 34 < 33 < 32 < 31 < 30
+ * V ^
+ * 37 29
+ * V ^
+ * 38 28
+ * V ^
+ * 39 27
+ * V ^
+ * 40 26
+ * V ^
+ * 41 25
+ * V
+ * 42 > 43 > 44 > 45 > 46 > 47 > 48
+ *
+ * And so on. I call the number of the square "v".
+ *
+ * Then there is the biggest number in the square, the one in the bottom right corner, I call that "g".
+ * g for square 1 (v = 1) is 8, for v = 2: g = 24, for v = 3: g = 48 and so on.
+ * We can see that each g is divisble by 8, but the multiplier is slightly tricky to find.
+ * The multiplier is the sum of all whole number from 1 up until v.
+ *
+ * Example:
+ * v = 2
+ * g = 8 * (Sum of numbers from 1 to v) = 8 * (1 + 2) = 8 * 3 = 24
+ *
+ * v = 3
+ * g = 8 * (Sum of numbers from 1 to v) = 8 * (1 + 2 + 3) = 8 * 6 = 48
+ *
+ * After we've found g and v, we start looking at the numbers in the corners.
+ * The bottom right corner is g by definition, the bottom left corner is g - 2 * v,
+ * the top left is g - 4 * v and the top right is g - 6 * v.
+ * By comparing the values in the corners we can determine where the number is:
+ * top row, bottom row, left column or right column.
+ *
+ * Example:
+ * v = 2, g = 24, n = 11
+ *
+ * if (n > bottom left corner) number is on bottom row (between 20 and 24)
+ * else if (n > top left corner) number is on left column (between 16 and 20)
+ * else if (n > top right corner) number is on top row (between 16 and 12)
+ * else number is on right column (between 12 and 9)
+ *
+ * After we find on which side the number is, we can immediately determine the x or y coordinate,
+ * as it will be +v or -v.
+ * The final step is to determine the other coordinate. The formula differs slightly depending on a side,
+ * but the gist of it is that we look at the difference between a corner number and our number, which gives
+ * us distance from the corner number and we offset the searched coordinate.
+ *
+ * Example:
+ * v = 2, g = 24, n = 11
+ * We have determined that our number is in the right column.
+ * This means we know for sure that the X coordinate of n is 2.
+ *
+ * offset = corner number - n = (g - 6 * v) - 11 = 12 - 11 = 1
+ *
+ * The Y coordinate of the corner number is 2 (12 is located at (2;2)).
+ * In our case, we want to subtract our offset from that coordinate, so
+ *
+ * Y coordinate of n = Y coordinate of corner number - offset = 2 - 1 = 1.
+ *
+ * And so we found that n is located at (2;1)
+ */
diff --git a/C++/LeibnizPI.cpp b/C++/LeibnizPI.cpp
new file mode 100644
index 0000000..2243f61
--- /dev/null
+++ b/C++/LeibnizPI.cpp
@@ -0,0 +1,26 @@
+#include <iostream>
+
+using namespace std;
+
+int main()
+{
+ cout << "n = ";
+ unsigned int n = 1;
+ cin >> n;
+ long double pid4 = 1;
+
+ for(unsigned int i = 0, dvsr = 3; i < n; i++, dvsr += 2) {
+ pid4 += ((i % 2) ? 1.0 : -1.0) / dvsr;
+ }
+
+ cout.precision(64);
+ cout << endl << pid4 * 4.0 << endl;
+
+ return 0;
+}
+
+/* This is a quick implementation of of the Leibniz formula for PI
+ * https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80
+ *
+ * Fun fact: you need around 100 million iterations for 7 correct decimal places
+ */
diff --git a/C++/QuadraticEquationGrapher.cpp b/C++/QuadraticEquationGrapher.cpp
new file mode 100644
index 0000000..7dfbe64
--- /dev/null
+++ b/C++/QuadraticEquationGrapher.cpp
@@ -0,0 +1,63 @@
+#include <iostream>
+#include <math.h>
+
+using namespace std;
+
+/* Program that graphs a quadratic equation on the standard output */
+
+/* Equation precision - how precise the quadratic equation result should be
+ * - higher values are more precise, but they could not show up on the graph
+ * - needs to be balanced with step
+ * Step - size of each unit (character)
+ */
+const int eqPrec = 1;
+const double step = 1;
+
+const char line = '*';
+const char verLine = '|';
+const char horLine = '-';
+const char empty = ' ';
+
+double quadr(double x, double a, double b, double c) {
+ return double( round( ( (a*pow(x, 2)) + (b*x) + c) * eqPrec ) / eqPrec);
+}
+
+void printQadr(int startx, int endx, int starty, int endy, double a, double b, double c) {
+ double currY, currX;
+ for (int y = max(starty, endy); y >= min(starty, endy); y--) {
+ for (int x = startx; x <= endx; x++) {
+ currY = y * step;
+ currX = x * step;
+
+ if (quadr(currX, a, b, c) == currY
+ || ((quadr(currX, a, b, c) < currY
+ || (quadr(currX - step, a, b, c) == 0 || quadr(currX + step, a, b, c) == 0)) // Wide lines
+ && (quadr(currX + step, a, b, c) > currY != quadr(currX - step, a, b, c) > currY)) // Long lines
+ ) {
+ cout << line;
+ } else if (x == 0) {
+ cout << verLine;
+ } else if (y == 0) {
+ cout << horLine;
+ } else {
+ cout << empty;
+ }
+ }
+ cout << endl;
+ }
+}
+
+void printQadr(int start, int end, double a, double b, double c) {
+ printQadr(start, end, start, end, a, b, c);
+}
+
+int main()
+{
+ double a = 0.2;
+ double b = 2;
+ double c = -10;
+
+ printQadr(-25, 15, 20, -15, a, b, c);
+
+ return 0;
+}
diff --git a/C++/README.md b/C++/README.md
new file mode 100644
index 0000000..4e4244f
--- /dev/null
+++ b/C++/README.md
@@ -0,0 +1,4 @@
+Building a file:
+```bash
+gcc -o program.out -lstdc++ FILE.cpp && ./program.out
+```