diff options
| -rw-r--r-- | challenge-008/paulo-custodio/c/ch-1.c | 69 | ||||
| -rw-r--r-- | challenge-008/paulo-custodio/c/ch-2.c | 60 | ||||
| -rw-r--r-- | challenge-008/paulo-custodio/cpp/ch-1.cpp | 67 | ||||
| -rw-r--r-- | challenge-008/paulo-custodio/cpp/ch-2.cpp | 38 | ||||
| -rw-r--r-- | challenge-008/paulo-custodio/t/test-1.yaml | 10 | ||||
| -rw-r--r-- | challenge-008/paulo-custodio/t/test-2.yaml | 9 | ||||
| -rw-r--r-- | challenge-008/paulo-custodio/test.pl | 33 |
7 files changed, 256 insertions, 30 deletions
diff --git a/challenge-008/paulo-custodio/c/ch-1.c b/challenge-008/paulo-custodio/c/ch-1.c new file mode 100644 index 0000000000..4043dada86 --- /dev/null +++ b/challenge-008/paulo-custodio/c/ch-1.c @@ -0,0 +1,69 @@ +/* +Challenge 008 + +Challenge #1 +Write a script that computes the first five perfect numbers. A perfect number +is an integer that is the sum of its positive proper divisors (all divisors +except itself). Please check Wiki for more information. This challenge was +proposed by Laurent Rosenfeld. +*/ + +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +bool is_prime(int n) { + if (n <= 1) + return false; + if (n <= 3) + return true; + if ((n % 2) == 0 || (n % 3) == 0) + return false; + for (int i = 5; i * i <= n; i += 6) + if ((n % i) == 0 || (n % (i + 2)) == 0) + return false; + return true; +} + +int next_prime(int n) { + if (n <= 1) + return 2; + do { + n++; + } while (!is_prime(n)); + return n; +} + +int ipow(int base, int exp) { + int result = 1; + for (;;) { + if (exp & 1) + result *= base; + exp >>= 1; + if (!exp) + break; + base *= base; + } + return result; +} + +// Euclid proved that 2 ^ (p-1) * (2 ^ p - 1) is an even perfect number +// whenever 2^p - 1 is prime +int next_perfect(void) { + static int p = 1; + while (true) { + p = next_prime(p); + int f = ipow(2, p) - 1; + if (is_prime(f)) + return ipow(2, p - 1) * f; + } +} + +int main(int argc, char* argv[]) { + int n = 5; + if (argc == 2) + n = atoi(argv[1]); + for (int i = 0; i < n; i++) { + printf("%d\n", next_perfect()); + } +} diff --git a/challenge-008/paulo-custodio/c/ch-2.c b/challenge-008/paulo-custodio/c/ch-2.c new file mode 100644 index 0000000000..c1f470df1d --- /dev/null +++ b/challenge-008/paulo-custodio/c/ch-2.c @@ -0,0 +1,60 @@ +/* +Challenge 008 + +Challenge #2 +Write a function, ‘center’, whose argument is a list of strings, which will +be lines of text. The function should insert spaces at the beginning of the +lines of text so that if they were printed, the text would be centered, and +return the modified lines. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define MAXLINE 1024 + +void* check_mem(void* p) { + if (!p) { + fputs("Out of memory", stderr); + exit(EXIT_FAILURE); + } + return p; +} + +void center(int nlines, char* lines[]) { + int max_len = 0; + + for (int i = 0; i < nlines; i++) { + int len = strlen(lines[i]); + if (len > max_len) + max_len = len; + } + + for (int i = 0; i < nlines; i++) { + char buffer[MAXLINE]; + int len = strlen(lines[i]); + sprintf(buffer, "%*s%s", (max_len - len) / 2, "", lines[i]); + strcpy(lines[i], buffer); + } +} + +int main(int argc, char* argv[]) { + argc--; argv++; + + int nlines = argc; + char** lines = check_mem(malloc(nlines * sizeof(char*))); + for (int i = 0; i < nlines; i++) { + lines[i] = check_mem(malloc(MAXLINE)); + strcpy(lines[i], argv[i]); + } + + center(nlines, lines); + + for (int i = 0; i < nlines; i++) + printf("%s\n", lines[i]); + + for (int i = 0; i < nlines; i++) + free(lines[i]); + free(lines); +} diff --git a/challenge-008/paulo-custodio/cpp/ch-1.cpp b/challenge-008/paulo-custodio/cpp/ch-1.cpp new file mode 100644 index 0000000000..9915f46bb8 --- /dev/null +++ b/challenge-008/paulo-custodio/cpp/ch-1.cpp @@ -0,0 +1,67 @@ +/* +Challenge 008 + +Challenge #1 +Write a script that computes the first five perfect numbers. A perfect number +is an integer that is the sum of its positive proper divisors (all divisors +except itself). Please check Wiki for more information. This challenge was +proposed by Laurent Rosenfeld. +*/ + +#include <iostream> +using namespace std; + +bool is_prime(int n) { + if (n <= 1) + return false; + if (n <= 3) + return true; + if ((n % 2) == 0 || (n % 3) == 0) + return false; + for (int i = 5; i * i <= n; i += 6) + if ((n % i) == 0 || (n % (i + 2)) == 0) + return false; + return true; +} + +int next_prime(int n) { + if (n <= 1) + return 2; + do { + n++; + } while (!is_prime(n)); + return n; +} + +int ipow(int base, int exp) { + int result = 1; + for (;;) { + if (exp & 1) + result *= base; + exp >>= 1; + if (!exp) + break; + base *= base; + } + return result; +} + +// Euclid proved that 2 ^ (p-1) * (2 ^ p - 1) is an even perfect number +// whenever 2^p - 1 is prime +int next_perfect(void) { + static int p = 1; + while (true) { + p = next_prime(p); + int f = ipow(2, p) - 1; + if (is_prime(f)) + return ipow(2, p - 1) * f; + } +} + +int main(int argc, char* argv[]) { + int n = 5; + if (argc == 2) + n = atoi(argv[1]); + for (int i = 0; i < n; i++) + cout << next_perfect() << endl; +} diff --git a/challenge-008/paulo-custodio/cpp/ch-2.cpp b/challenge-008/paulo-custodio/cpp/ch-2.cpp new file mode 100644 index 0000000000..aeca0d65e4 --- /dev/null +++ b/challenge-008/paulo-custodio/cpp/ch-2.cpp @@ -0,0 +1,38 @@ +/* +Challenge 008 + +Challenge #2 +Write a function, ‘center’, whose argument is a list of strings, which will +be lines of text. The function should insert spaces at the beginning of the +lines of text so that if they were printed, the text would be centered, and +return the modified lines. +*/ + +#include <iostream> +#include <vector> +#include <string> +using namespace std; + +void center(vector<string>& lines) { + size_t max_len = 0; + + for (auto& line : lines) + if (line.size() > max_len) + max_len = line.size(); + + for (auto& line : lines) + line = string((max_len - static_cast<int>(line.size())) / 2, ' ') + line; +} + +int main(int argc, char* argv[]) { + argc--; argv++; + + vector<string> lines; + for (int i = 0; i < argc; i++) + lines.push_back(argv[i]); + + center(lines); + + for (auto& line : lines) + cout << line << endl; +} diff --git a/challenge-008/paulo-custodio/t/test-1.yaml b/challenge-008/paulo-custodio/t/test-1.yaml new file mode 100644 index 0000000000..90fe6af462 --- /dev/null +++ b/challenge-008/paulo-custodio/t/test-1.yaml @@ -0,0 +1,10 @@ +- setup: + cleanup: + args: 5 + input: + output: | + 6 + 28 + 496 + 8128 + 33550336 diff --git a/challenge-008/paulo-custodio/t/test-2.yaml b/challenge-008/paulo-custodio/t/test-2.yaml new file mode 100644 index 0000000000..254dc33be8 --- /dev/null +++ b/challenge-008/paulo-custodio/t/test-2.yaml @@ -0,0 +1,9 @@ +- setup: + cleanup: + args: "'This' 'is' 'a test of the' 'center function'" + input: + output: | + | This + | is + | a test of the + |center function diff --git a/challenge-008/paulo-custodio/test.pl b/challenge-008/paulo-custodio/test.pl index 6897ad608e..ba6c37260b 100644 --- a/challenge-008/paulo-custodio/test.pl +++ b/challenge-008/paulo-custodio/test.pl @@ -1,31 +1,4 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use 5.030; +#!/usr/bin/env perl +use Modern::Perl; use Test::More; - -is capture("perl perl/ch-1.pl 5"), <<END; -6 -28 -496 -8128 -33550336 -END - -is capture("perl perl/ch-2.pl 'This' 'is' 'a test of the' 'center function'"), <<END; - This - is - a test of the -center function -END - -done_testing; - - -sub capture { - my($cmd) = @_; - my $out = `$cmd`; - $out =~ s/[ \r\t]*\n/\n/g; - return $out; -} +require '../../challenge-001/paulo-custodio/test.pl'; |
