From 4b88d354f628182beeb25ad76f57e8a616ff30c1 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Wed, 15 Sep 2021 15:53:59 +0300 Subject: Renamed C++ folder to accomodate C files --- C_C++/FindSpiralNumber.cpp | 179 +++++++++++++++++++++++++++++++++++++ C_C++/FindSpiralNumberCoord.cpp | 147 ++++++++++++++++++++++++++++++ C_C++/LeibnizPI.cpp | 26 ++++++ C_C++/QuadraticEquationGrapher.cpp | 63 +++++++++++++ 4 files changed, 415 insertions(+) create mode 100644 C_C++/FindSpiralNumber.cpp create mode 100644 C_C++/FindSpiralNumberCoord.cpp create mode 100644 C_C++/LeibnizPI.cpp create mode 100644 C_C++/QuadraticEquationGrapher.cpp (limited to 'C_C++') diff --git a/C_C++/FindSpiralNumber.cpp b/C_C++/FindSpiralNumber.cpp new file mode 100644 index 0000000..78e1681 --- /dev/null +++ b/C_C++/FindSpiralNumber.cpp @@ -0,0 +1,179 @@ +#include + +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_C++/FindSpiralNumberCoord.cpp b/C_C++/FindSpiralNumberCoord.cpp new file mode 100644 index 0000000..07b2071 --- /dev/null +++ b/C_C++/FindSpiralNumberCoord.cpp @@ -0,0 +1,147 @@ +#include + +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_C++/LeibnizPI.cpp b/C_C++/LeibnizPI.cpp new file mode 100644 index 0000000..2243f61 --- /dev/null +++ b/C_C++/LeibnizPI.cpp @@ -0,0 +1,26 @@ +#include + +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_C++/QuadraticEquationGrapher.cpp b/C_C++/QuadraticEquationGrapher.cpp new file mode 100644 index 0000000..7dfbe64 --- /dev/null +++ b/C_C++/QuadraticEquationGrapher.cpp @@ -0,0 +1,63 @@ +#include +#include + +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; +} -- cgit v1.2.3