From 1784430e7ffd5849a14297f3da144153f326204f Mon Sep 17 00:00:00 2001 From: sijanec Date: Tue, 8 Dec 2020 22:14:47 +0100 Subject: =?UTF-8?q?euler=2017=20+=20izdelovalec=20angle=C5=A1kih=20=C5=A1t?= =?UTF-8?q?evilk=20s=20=C4=8Drkami=20iz=20=C5=A1tevilk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mat/euler/17/a.out | Bin 13136 -> 13192 bytes mat/euler/17/angnum.c | 81 +++++++++++++++++++++++++++++++++++--------------- mat/euler/17/prog.c | 28 +++++++++++++++++ 3 files changed, 85 insertions(+), 24 deletions(-) create mode 100644 mat/euler/17/prog.c diff --git a/mat/euler/17/a.out b/mat/euler/17/a.out index e04ac3d..e83fc19 100755 Binary files a/mat/euler/17/a.out and b/mat/euler/17/a.out differ diff --git a/mat/euler/17/angnum.c b/mat/euler/17/angnum.c index 5c5f890..2f16d75 100644 --- a/mat/euler/17/angnum.c +++ b/mat/euler/17/angnum.c @@ -18,7 +18,7 @@ #define J_12 "twelve" #define J_13 "thirteen" #define J_14 "fourteen" -#define J_15 "fiveteen" +#define J_15 "fifteen" #define J_16 "sixteen" #define J_17 "seventeen" #define J_18 "eighteen" @@ -36,18 +36,17 @@ #define J_1M "million" #define J_1G "billion" #define J_1T "trillion" +#define J_1P "quadrillion" +#define J_1E "quintillion" +#define J_1Z "sextillion" +#define J_1Y "septillion" #define J_AND "and" +#define J_NEG "negative" #define J_EMPTY "" /* definiramo jezik - KONEC */ #define MX_NS_L 1337 -/* angnum : size_t (število zapisanih bajtov, -1 ob propadu sveta) - * n: lluint: številka, ki naj jo zapišemo - * s: pointer to allocatanega spomina, kamor zapišemo string - * l: število bajtov allocatanega spomina za string, IZključno zadnjega '\0' - * alocirati morate vsaj en bajt več od l - * string bo mogoče avtomatsko null terminiran, vseeno ga raje dajte še sami */ char * j_enice[] = { J_EMPTY, J_1, J_2, J_3, J_4, J_5, J_6, J_7, J_8, J_9, J_10, J_11, J_12, J_13, J_14, J_15, J_16, J_17, J_18, J_19, J_20 }; -char * j_power[] = { J_EMPTY, J_1k, J_1M, J_1G, J_1T }; +char * j_power[] = { J_EMPTY, J_1k, J_1M, J_1G, J_1T, J_1P, J_1E, J_1Z, J_1Y }; char * j_desetice[] = { J_EMPTY, J_10, J_20, J_30, J_40, J_50, J_60, J_70, J_80, J_90 }; unsigned long long int na(unsigned long long int a, unsigned long long int b) { @@ -58,12 +57,18 @@ unsigned long long int na(unsigned long long int a, unsigned long long int b) { return c; } -size_t angnum (unsigned long long int n, char * s, int l) { +/* private_angnum : size_t (število zapisanih bajtov, -1 ob propadu sveta) + * n: lluint: številka, ki naj jo zapišemo + * s: pointer to allocatanega spomina, kamor zapišemo string + * l: število bajtov allocatanega spomina za string, IZključno zadnjega '\0' + * alocirati morate vsaj en bajt več od l + * string bo mogoče avtomatsko null terminiran, vseeno ga raje dajte še sami + * UPORABLJAJTE RAJE angnum NAMESTO private_angnum */ +size_t private_angnum (unsigned long long int n, char * s, int l) { unsigned int i = 0; // Index Iteracij int z = 0; // Zapisanih if (n <= 20) { // "thirteen", namesto 0 je prazen string z = snprintf(s, l, "%s", j_enice[n]); - fprintf(stderr, "z = %d, l = %d, s = %s, n = %llu\n", z, l, s, n); return z; } if (n <= 99) { // && n > 20 // "forty-one" ali "thirty" @@ -77,7 +82,7 @@ size_t angnum (unsigned long long int n, char * s, int l) { if (n % 100 != 0) { if (z < l) s[z++] = ' '; z = z + snprintf(s+z, l-z, "%s ", J_AND); // "and " - return z + angnum(n-(n/100)*100, s+z, l-z); + return z + private_angnum(n-(n/100)*100, s+z, l-z); } else { return z; } @@ -85,31 +90,59 @@ size_t angnum (unsigned long long int n, char * s, int l) { for (i = 3; i <= 21; i=i+3) // sedaj iščemo največjo tisočico if (n / na(10, i) <= 999) // zadnja tisočica break; - z = angnum((n/na(10, i)), s, l-z); // "three hundred and forty-two" - fprintf(stderr, "-z = %d, l = %d, s = %s, n = %llu\n", z, l, s, n); + z = private_angnum((n/na(10, i)), s, l-z); // "three hundred forty-two" z = z + snprintf(s+z, l-z, " %s", j_power[i/3]); // "million" - fprintf(stderr, "xz = %d, l = %d, s = %s, n = %llu\n", z, l, s, n); if (n-(n/na(i, 10)) > 0) { - fprintf(stderr, "pz = %d, l = %d, s = %s, n = %llu\n", z, l, s, n); if (z < l) s[z++] = ' '; - if (z < l) s[z++] = 'a'; - if (z < l) s[z++] = 'n'; - if (z < l) s[z++] = 'd'; + z = z + private_angnum(n-(n/na(10, i)*na(10, i)), s+z, l-z); + } + return z; +} +/* + * angnum(n, s, sizeof) : size_t napisanih bajtov, vključno z nul bajtom + * n je celo, ki ga je treba napisati. lahko je 0, negativno ali pozit.. + * s je pointer do char, kamor naj se piše številka. + * sizeof je velikost alocatanega spomina za s, vključno z nul bajtom, naj bo>0. + * funkcija vrne število napisanih bajtov ali pa 0 v primeru napake. + * če je vrednost 0, je vsebina spomina od s do s+sizeof neopredeljena. + * število se zapiše v britanskem formatu, s pomišljajem in and. + * niz je končan z nul bajtom in pripravljen na tiskanje. + * četudi je string uspešno napisan, lahko funkcija odvrne 0, če se bliža + * omejitvi prostora sizeof. prav tako, četudi je dovolj prostora, + * lahko funkcija napiše napačno vrednost v s, če se bliža omejitvi, zato je + * nastavljen check, da funkcija odvrne 0, če je omejitev prostora 10+-2 + * bajtov stran od napisanega. + * funkcija naj ne bi pisala preko omejitve sizeof. + * */ +size_t angnum (long long int n, char * s, int l) { + size_t z = 0; + size_t i = 0; + if (n == 0) { + z = snprintf(s, l, "%s", J_0); + return z; + } + if (n < 0) { + z = snprintf(s, l, "%s", J_NEG); if (z < l) s[z++] = ' '; - fprintf(stderr, "qz = %d, l = %d, s = %s, n = %llu\n", z, l, s, n); - z = z + angnum(n-(n/na(10, i)*na(10, i)), s+z, l-z); - fprintf(stderr, "zz = %d, l = %d, s = %s, n = %llu\n", z, l, s, n); + z = z + private_angnum(abs(n), s+z, (l-z)-1); + } else { + z = z + private_angnum(n, s+z, (l-z)-1); } + if (z < l) s[z++] = '\0'; + if (l - z < 10) + return 0; return z; } +#ifndef DISABLE_LIB_TESTS int main (int argc, char ** argv) { if (argc != 1+1) { fprintf(stderr, "uporaba: %s \nprimer, ki napiše \"four hundred and twenty\": %s 420\n", argv[0], argv[0]); return 1; } - unsigned long long int n = strtoll(argv[1], NULL, 10); + long long int n = strtoll(argv[1], NULL, 10); char * s = malloc(sizeof(char)*MX_NS_L); - s[angnum(n, s, MX_NS_L-1)] = '\0'; + size_t r = angnum(n, s, MX_NS_L); fprintf(stdout, "%s\n", s); - return 0; + return r == 0 ? 2 : 0; } +#endif diff --git a/mat/euler/17/prog.c b/mat/euler/17/prog.c new file mode 100644 index 0000000..afa005d --- /dev/null +++ b/mat/euler/17/prog.c @@ -0,0 +1,28 @@ +#include +#include +#define DISABLE_LIB_TESTS 1 +#include +int main (int argc, char ** argv) { + if (argc != 1+2) { + fprintf(stderr, "uporaba: %s \nprimer-sešteje črke v ang številih od 1 do 1000: %s 1 1000\n", argv[0], argv[0]); + return 1; + } + long long int a = strtoll(argv[1], NULL, 10); + long long int b = strtoll(argv[2], NULL, 10); + unsigned long long int i = 0; // lenasI + long long int j = 0; // Janez je podpisan, da se po 0 ne obrne (: + unsigned long long int e = 0; // sEštevek + char * s = malloc(sizeof(char)*MX_NS_L); + for (i = a; i <= b; i++) { + // fprintf(stderr, "\rračunam ... preostane še %llu operacij.", b-i); + j = angnum(i, s, MX_NS_L); + if (j == 0) + return 2; + for (j-- /* da ne gledamo nul bajta na koncu (: */ ; j >= 0; j--) { + if (s[j] >= 'a' && s[j] <= 'z') // that's why I like C + e++; + } + } + fprintf(stdout, "\rkonec. seštevek črk je %llu.\n", e); + return 0; +} -- cgit v1.2.3