Это мой подход к решению эйлера № 8.Сначала он использует функцию strok(3)
для разделения всей строки на части, разделенные символами 0
.Затем он перемещает окно длиной n
по разделенным строкам (строки длиной менее n
не могут получить достаточно цифр, чтобы сформировать продукт без использования 0
, поэтому они отбрасываются.
Затем мысоздайте первый продукт, умножив первый набор цифр n
. После того, как он установлен, окно разбивается на части, путем умножения продукта на следующую цифру и деления продукта на последнюю цифру в очереди, указанную на p
и q
. Продукты сравниваются с максимумом и, если они больше, сохраняются положение совпадения и новое значение продукта.
В конце печатается подстрока, начиная ссохраненная позиция, индекс распечатывается и продукт.
Программа принимает опции -n
и -v
:
-n
число позволяет указать другое число (по умолчанию 13, как указывает euler # 8) -v
производит больше выходных данных, указывая на каждом шаге тестируемую строку, и tВовлеченные продукты.
Чтобы скомпилировать программу, просто:
cc -o 8 8.c
и для ее запуска просто выполните 8
в командной строке.
Если вы не хотите видеть решение, не продолжайте читать.
8.c
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#define FLAG_VERBOSE (1 << 0)
int flags = 0;
int n = 13;
char N[] =
"73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
"85861560789112949495459501737958331952853208805511"
"12540698747158523863050715693290963295227443043557"
"66896648950445244523161731856403098711121722383113"
"62229893423380308135336276614282806444486645238749"
"30358907296290491560440772390713810515859307960866"
"70172427121883998797908792274921901699720888093776"
"65727333001053367881220235421809751254540594752243"
"52584907711670556013604839586446706324415722155397"
"53697817977846174064955149290862569321978468622482"
"83972241375657056057490261407972968652414535100474"
"82166370484403199890008895243450658541227588666881"
"16427171479924442928230863465674813919123162824586"
"17866458359124566529476545682848912883142607690042"
"24219022671055626321111109370544217506941658960408"
"07198403850962455444362981230987879927244284909188"
"84580156166097919133875499200524063689912560717606"
"05886116467109405077541002256983155200055935729725"
"71636269561882670428252483600823257530420752963450";
int main(int argc, char **argv)
{
int opt;
while ((opt = getopt(argc, argv, "n:v")) != EOF) {
switch (opt) {
case 'n':
if (sscanf(optarg, "%d", &n) != 1) {
fprintf(stderr,
"invalid number: %s\n",
optarg);
}
break;
case 'v':
flags |= FLAG_VERBOSE;
break;
} /* switch */
} /* while */
if (flags & FLAG_VERBOSE) {
printf( "n = %d;\n"
"N = \"%s\"\n",
n, N);
}
char *p, *res = NULL;
unsigned long long res_prod = 0;
for (p = strtok(N, "0"); p; p = strtok(NULL, "0")) {
if (strlen(p) < n) continue;
char *q = p;
unsigned long long prod = 1LL;
int i;
for (i = 0; i < n; i++) { /* initial product */
prod *= *p++ - '0';
}
for(;;) {
int larger = prod > res_prod;
if (flags & FLAG_VERBOSE)
printf("Trying %.*s ==> %llu%s\n",
n, q, prod,
larger ? " !" : "");
if (larger) {
res = q; res_prod = prod;
}
if (!*p) break;
prod /= *q++ - '0';
prod *= *p++ - '0';
}
}
if (res) {
int pos = res - N;
printf("Largest product at position %d (%s%.*s%s): %llu\n",
pos,
pos ? "..." : "", n, res,
pos < sizeof N - 1 - n ? "..." : "",
res_prod);
} else {
printf("No solution found\n");
}
}