aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-008/paulo-custodio/c/ch-1.c69
-rw-r--r--challenge-008/paulo-custodio/c/ch-2.c60
-rw-r--r--challenge-008/paulo-custodio/cpp/ch-1.cpp67
-rw-r--r--challenge-008/paulo-custodio/cpp/ch-2.cpp38
-rw-r--r--challenge-008/paulo-custodio/t/test-1.yaml10
-rw-r--r--challenge-008/paulo-custodio/t/test-2.yaml9
-rw-r--r--challenge-008/paulo-custodio/test.pl33
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';