aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-11-16 22:24:20 +0000
committerGitHub <noreply@github.com>2023-11-16 22:24:20 +0000
commitba554acc2a377b6d548b9010df056345af03099e (patch)
tree3bc4547da5ef7252b2a3ceca9c510705cc029fb0
parent976af75105a156de9788a51c3c62391ac81995a5 (diff)
parent30dd5829754827713d68b03deeb90762d0b95fef (diff)
downloadperlweeklychallenge-club-ba554acc2a377b6d548b9010df056345af03099e.tar.gz
perlweeklychallenge-club-ba554acc2a377b6d548b9010df056345af03099e.tar.bz2
perlweeklychallenge-club-ba554acc2a377b6d548b9010df056345af03099e.zip
Merge pull request #9078 from pauloscustodio/master
Add Perl solution
-rw-r--r--challenge-241/paulo-custodio/Makefile2
-rw-r--r--challenge-241/paulo-custodio/c/ch-1.c97
-rw-r--r--challenge-241/paulo-custodio/c/ch-2.c146
-rw-r--r--challenge-241/paulo-custodio/c/utarray.h252
-rw-r--r--challenge-241/paulo-custodio/cpp/ch-1.cpp92
-rw-r--r--challenge-241/paulo-custodio/cpp/ch-2.cpp120
-rw-r--r--challenge-241/paulo-custodio/perl/ch-1.pl71
-rw-r--r--challenge-241/paulo-custodio/perl/ch-2.pl67
-rw-r--r--challenge-241/paulo-custodio/t/test-1.yaml10
-rw-r--r--challenge-241/paulo-custodio/t/test-2.yaml10
10 files changed, 867 insertions, 0 deletions
diff --git a/challenge-241/paulo-custodio/Makefile b/challenge-241/paulo-custodio/Makefile
new file mode 100644
index 0000000000..c3c762d746
--- /dev/null
+++ b/challenge-241/paulo-custodio/Makefile
@@ -0,0 +1,2 @@
+all:
+ perl ../../challenge-001/paulo-custodio/test.pl
diff --git a/challenge-241/paulo-custodio/c/ch-1.c b/challenge-241/paulo-custodio/c/ch-1.c
new file mode 100644
index 0000000000..9d188a29f8
--- /dev/null
+++ b/challenge-241/paulo-custodio/c/ch-1.c
@@ -0,0 +1,97 @@
+/*
+Challenge 241
+
+Task 1: Arithmetic Triplets
+Submitted by: Mohammad S Anwar
+
+You are given an array (3 or more members) of integers in increasing order
+and a positive integer.
+
+Write a script to find out the number of unique Arithmetic Triplets satisfying
+the following rules:
+
+a) i < j < k
+b) nums[j] - nums[i] == diff
+c) nums[k] - nums[j] == diff
+
+Example 1
+
+Input: @nums = (0, 1, 4, 6, 7, 10)
+ $diff = 3
+Output: 2
+
+Index (1, 2, 4) is an arithmetic triplet because both 7 - 4 == 3 and 4 - 1 == 3.
+Index (2, 4, 5) is an arithmetic triplet because both 10 - 7 == 3 and 7 - 4 == 3.
+
+Example 2
+
+Input: @nums = (4, 5, 6, 7, 8, 9)
+ $diff = 2
+Output: 2
+
+(0, 2, 4) is an arithmetic triplet because both 8 - 6 == 2 and 6 - 4 == 2.
+(1, 3, 5) is an arithmetic triplet because both 9 - 7 == 2 and 7 - 5 == 2.
+*/
+
+#include "utarray.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int count_triplets(UT_array* nums, int diff) {
+ int count = 0;
+ for (size_t i = 0; i < utarray_len(nums) - 2; i++) {
+ int ni = *(int*)utarray_eltptr(nums, i);
+ for (size_t j = i + 1; j < utarray_len(nums) - 1; j++) {
+ int nj = *(int*)utarray_eltptr(nums, j);
+ for (size_t k = j + 1; k < utarray_len(nums); k++) {
+ int nk = *(int*)utarray_eltptr(nums, k);
+ if (nj - ni == diff && nk - nj == diff)
+ count++;
+ }
+ }
+ }
+ return count;
+}
+
+void usage(void) {
+ puts("Usage: ch-1 -nums n n n ... -diff n\n");
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char* argv[]) {
+ UT_array* nums;
+ utarray_new(nums, &ut_int_icd);
+ int diff = -1;
+
+ // parse args
+ int i = 1;
+ while (i < argc) {
+ if (0 == strcmp(argv[i], "-nums")) {
+ i++;
+ while (i < argc && argv[i][0] != '-') {
+ int n = atoi(argv[i]);
+ utarray_push_back(nums, &n);
+ i++;
+ }
+ }
+ else if (0 == strcmp(argv[i], "-diff")) {
+ i++;
+ if (i < argc) {
+ diff = atoi(argv[i]);
+ i++;
+ }
+ }
+ else {
+ usage();
+ }
+ }
+ if (utarray_len(nums) == 0 || diff < 0)
+ usage();
+
+ // process
+ int count = count_triplets(nums, diff);
+ printf("%d\n", count);
+
+ utarray_free(nums);
+}
diff --git a/challenge-241/paulo-custodio/c/ch-2.c b/challenge-241/paulo-custodio/c/ch-2.c
new file mode 100644
index 0000000000..91f49eed5c
--- /dev/null
+++ b/challenge-241/paulo-custodio/c/ch-2.c
@@ -0,0 +1,146 @@
+/*
+Challenge 241
+
+Task 2: Prime Order
+Submitted by: Mohammad S Anwar
+
+You are given an array of unique positive integers greater than 2.
+
+Write a script to sort them in ascending order of the count of their prime
+factors, tie-breaking by ascending value.
+Example 1
+
+Input: @int = (11, 8, 27, 4)
+Output: (11, 4, 8, 27))
+
+Prime factors of 11 => 11
+Prime factors of 4 => 2, 2
+Prime factors of 8 => 2, 2, 2
+Prime factors of 27 => 3, 3, 3
+*/
+
+#include "utarray.h"
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct {
+ int n;
+ UT_array* factors;
+} Num;
+
+void die(const char* message, ...) {
+ va_list ap;
+ va_start(ap, message);
+ vfprintf(stderr, message, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+void* check_mem(void* p) {
+ if (!p)
+ die("Out of memory");
+ return p;
+}
+
+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;
+}
+
+void prime_factors(UT_array* out, int n) {
+ if (n < 2) {
+ int p = 1;
+ utarray_push_back(out, &p);
+ }
+ else {
+ int p = 2;
+ while (n > 1) {
+ while (n % p == 0) {
+ utarray_push_back(out, &p);
+ n /= p;
+ }
+ p = next_prime(p);
+ }
+ }
+}
+
+Num* num_new(int n) {
+ Num* num = check_mem(calloc(1, sizeof(Num)));
+ num->n = n;
+ utarray_new(num->factors, &ut_int_icd);
+ prime_factors(num->factors, n);
+ return num;
+}
+
+void num_free(Num* num) {
+ utarray_free(num->factors);
+ free(num);
+}
+
+int num_compare(const void* a_, const void* b_) {
+ const Num* a = *(Num**)a_;
+ const Num* b = *(Num**)b_;
+ int a_size = (int)utarray_len(a->factors);
+ int b_size = (int)utarray_len(b->factors);
+ if (a_size != b_size)
+ return a_size - b_size;
+ for (size_t i = 0; i < a_size; i++) {
+ int a1 = *(int*)utarray_eltptr(a->factors, i);
+ int b1 = *(int*)utarray_eltptr(b->factors, i);
+ if (a1 != b1)
+ return a1 - b1;
+ }
+ return 0;
+}
+
+int main(int argc, char* argv[]) {
+ if (argc < 2) {
+ puts("Usage: ch-2 n n n ...\n");
+ exit(EXIT_FAILURE);
+ }
+
+ UT_array* nums;
+ utarray_new(nums, &ut_ptr_icd);
+
+ // parse args and compute primes
+ for (int i = 1; i < argc; i++) {
+ int n = atoi(argv[i]);
+ Num* num = num_new(n);
+ utarray_push_back(nums, &num);
+ }
+
+ // sort
+ qsort(utarray_eltptr(nums, 0), utarray_len(nums), sizeof(Num*), num_compare);
+
+ // output
+ const char* sep = "";
+ for (size_t i = 0; i < utarray_len(nums); i++) {
+ printf("%s%d", sep, (*(Num**)utarray_eltptr(nums, i))->n);
+ sep = " ";
+ }
+
+ // free data
+ for (size_t i = 0; i < utarray_len(nums); i++)
+ num_free(*(Num**)utarray_eltptr(nums, i));
+ utarray_free(nums);
+}
diff --git a/challenge-241/paulo-custodio/c/utarray.h b/challenge-241/paulo-custodio/c/utarray.h
new file mode 100644
index 0000000000..1fe8bc1c74
--- /dev/null
+++ b/challenge-241/paulo-custodio/c/utarray.h
@@ -0,0 +1,252 @@
+/*
+Copyright (c) 2008-2022, Troy D. Hanson https://troydhanson.github.io/uthash/
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* a dynamic array implementation using macros
+ */
+#ifndef UTARRAY_H
+#define UTARRAY_H
+
+#define UTARRAY_VERSION 2.3.0
+
+#include <stddef.h> /* size_t */
+#include <string.h> /* memset, etc */
+#include <stdlib.h> /* exit */
+
+#ifdef __GNUC__
+#define UTARRAY_UNUSED __attribute__((__unused__))
+#else
+#define UTARRAY_UNUSED
+#endif
+
+#ifndef utarray_oom
+#define utarray_oom() exit(-1)
+#endif
+
+typedef void (ctor_f)(void *dst, const void *src);
+typedef void (dtor_f)(void *elt);
+typedef void (init_f)(void *elt);
+typedef struct {
+ size_t sz;
+ init_f *init;
+ ctor_f *copy;
+ dtor_f *dtor;
+} UT_icd;
+
+typedef struct {
+ unsigned i,n;/* i: index of next available slot, n: num slots */
+ UT_icd icd; /* initializer, copy and destructor functions */
+ char *d; /* n slots of size icd->sz*/
+} UT_array;
+
+#define utarray_init(a,_icd) do { \
+ memset(a,0,sizeof(UT_array)); \
+ (a)->icd = *(_icd); \
+} while(0)
+
+#define utarray_done(a) do { \
+ if ((a)->n) { \
+ if ((a)->icd.dtor) { \
+ unsigned _ut_i; \
+ for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
+ (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \
+ } \
+ } \
+ free((a)->d); \
+ } \
+ (a)->n=0; \
+} while(0)
+
+#define utarray_new(a,_icd) do { \
+ (a) = (UT_array*)malloc(sizeof(UT_array)); \
+ if ((a) == NULL) { \
+ utarray_oom(); \
+ } \
+ utarray_init(a,_icd); \
+} while(0)
+
+#define utarray_free(a) do { \
+ utarray_done(a); \
+ free(a); \
+} while(0)
+
+#define utarray_reserve(a,by) do { \
+ if (((a)->i+(by)) > (a)->n) { \
+ char *utarray_tmp; \
+ while (((a)->i+(by)) > (a)->n) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \
+ utarray_tmp=(char*)realloc((a)->d, (a)->n*(a)->icd.sz); \
+ if (utarray_tmp == NULL) { \
+ utarray_oom(); \
+ } \
+ (a)->d=utarray_tmp; \
+ } \
+} while(0)
+
+#define utarray_push_back(a,p) do { \
+ utarray_reserve(a,1); \
+ if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \
+ else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \
+} while(0)
+
+#define utarray_pop_back(a) do { \
+ if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \
+ else { (a)->i--; } \
+} while(0)
+
+#define utarray_extend_back(a) do { \
+ utarray_reserve(a,1); \
+ if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \
+ else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \
+ (a)->i++; \
+} while(0)
+
+#define utarray_len(a) ((a)->i)
+
+#define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL)
+#define _utarray_eltptr(a,j) ((void*)((a)->d + ((a)->icd.sz * (j))))
+
+#define utarray_insert(a,p,j) do { \
+ if ((j) > (a)->i) utarray_resize(a,j); \
+ utarray_reserve(a,1); \
+ if ((j) < (a)->i) { \
+ memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \
+ ((a)->i - (j))*((a)->icd.sz)); \
+ } \
+ if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \
+ else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \
+ (a)->i++; \
+} while(0)
+
+#define utarray_inserta(a,w,j) do { \
+ if (utarray_len(w) == 0) break; \
+ if ((j) > (a)->i) utarray_resize(a,j); \
+ utarray_reserve(a,utarray_len(w)); \
+ if ((j) < (a)->i) { \
+ memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \
+ _utarray_eltptr(a,j), \
+ ((a)->i - (j))*((a)->icd.sz)); \
+ } \
+ if ((a)->icd.copy) { \
+ unsigned _ut_i; \
+ for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \
+ (a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \
+ } \
+ } else { \
+ memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \
+ utarray_len(w)*((a)->icd.sz)); \
+ } \
+ (a)->i += utarray_len(w); \
+} while(0)
+
+#define utarray_resize(dst,num) do { \
+ unsigned _ut_i; \
+ if ((dst)->i > (unsigned)(num)) { \
+ if ((dst)->icd.dtor) { \
+ for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \
+ (dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \
+ } \
+ } \
+ } else if ((dst)->i < (unsigned)(num)) { \
+ utarray_reserve(dst, (num) - (dst)->i); \
+ if ((dst)->icd.init) { \
+ for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \
+ (dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \
+ } \
+ } else { \
+ memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz*((num) - (dst)->i)); \
+ } \
+ } \
+ (dst)->i = (num); \
+} while(0)
+
+#define utarray_concat(dst,src) do { \
+ utarray_inserta(dst, src, utarray_len(dst)); \
+} while(0)
+
+#define utarray_erase(a,pos,len) do { \
+ if ((a)->icd.dtor) { \
+ unsigned _ut_i; \
+ for (_ut_i = 0; _ut_i < (len); _ut_i++) { \
+ (a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \
+ } \
+ } \
+ if ((a)->i > ((pos) + (len))) { \
+ memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \
+ ((a)->i - ((pos) + (len))) * (a)->icd.sz); \
+ } \
+ (a)->i -= (len); \
+} while(0)
+
+#define utarray_renew(a,u) do { \
+ if (a) utarray_clear(a); \
+ else utarray_new(a, u); \
+} while(0)
+
+#define utarray_clear(a) do { \
+ if ((a)->i > 0) { \
+ if ((a)->icd.dtor) { \
+ unsigned _ut_i; \
+ for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
+ (a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \
+ } \
+ } \
+ (a)->i = 0; \
+ } \
+} while(0)
+
+#define utarray_sort(a,cmp) do { \
+ qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \
+} while(0)
+
+#define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp)
+
+#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL)
+#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : (((a)->i != utarray_eltidx(a,e)+1) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL))
+#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) != 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL))
+#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL)
+#define utarray_eltidx(a,e) (((char*)(e) - (a)->d) / (a)->icd.sz)
+
+/* last we pre-define a few icd for common utarrays of ints and strings */
+static void utarray_str_cpy(void *dst, const void *src) {
+ char *const *srcc = (char *const *)src;
+ char **dstc = (char**)dst;
+ if (*srcc == NULL) {
+ *dstc = NULL;
+ } else {
+ *dstc = (char*)malloc(strlen(*srcc) + 1);
+ if (*dstc == NULL) {
+ utarray_oom();
+ } else {
+ strcpy(*dstc, *srcc);
+ }
+ }
+}
+static void utarray_str_dtor(void *elt) {
+ char **eltc = (char**)elt;
+ if (*eltc != NULL) free(*eltc);
+}
+static const UT_icd ut_str_icd UTARRAY_UNUSED = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor};
+static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int),NULL,NULL,NULL};
+static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void*),NULL,NULL,NULL};
+
+
+#endif /* UTARRAY_H */
diff --git a/challenge-241/paulo-custodio/cpp/ch-1.cpp b/challenge-241/paulo-custodio/cpp/ch-1.cpp
new file mode 100644
index 0000000000..13868c150f
--- /dev/null
+++ b/challenge-241/paulo-custodio/cpp/ch-1.cpp
@@ -0,0 +1,92 @@
+/*
+Challenge 241
+
+Task 1: Arithmetic Triplets
+Submitted by: Mohammad S Anwar
+
+You are given an array (3 or more members) of integers in increasing order
+and a positive integer.
+
+Write a script to find out the number of unique Arithmetic Triplets satisfying
+the following rules:
+
+a) i < j < k
+b) nums[j] - nums[i] == diff
+c) nums[k] - nums[j] == diff
+
+Example 1
+
+Input: @nums = (0, 1, 4, 6, 7, 10)
+ $diff = 3
+Output: 2
+
+Index (1, 2, 4) is an arithmetic triplet because both 7 - 4 == 3 and 4 - 1 == 3.
+Index (2, 4, 5) is an arithmetic triplet because both 10 - 7 == 3 and 7 - 4 == 3.
+
+Example 2
+
+Input: @nums = (4, 5, 6, 7, 8, 9)
+ $diff = 2
+Output: 2
+
+(0, 2, 4) is an arithmetic triplet because both 8 - 6 == 2 and 6 - 4 == 2.
+(1, 3, 5) is an arithmetic triplet because both 9 - 7 == 2 and 7 - 5 == 2.
+*/
+
+#include <iostream>
+#include <string>
+#include <vector>
+using namespace std;
+
+int count_triplets(vector<int>& nums, int diff) {
+ int count = 0;
+ for (int i = 0; i < static_cast<int>(nums.size()) - 2; i++) {
+ for (int j = i + 1; j < static_cast<int>(nums.size()) - 1; j++) {
+ for (int k = j + 1; k < static_cast<int>(nums.size()); k++) {
+ if (nums[j] - nums[i] == diff && nums[k] - nums[j] == diff)
+ count++;
+ }
+ }
+ }
+ return count;
+}
+
+void usage(void) {
+ cerr << "Usage: ch-1 -nums n n n ... -diff n" << endl;
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char* argv[]) {
+ vector<int> nums;
+ int diff = -1;
+
+ // parse args
+ int i = 1;
+ while (i < argc) {
+ string arg = argv[i];
+ if (arg == "-nums") {
+ i++;
+ while (i < argc && argv[i][0] != '-') {
+ int n = atoi(argv[i]);
+ nums.push_back(n);
+ i++;
+ }
+ }
+ else if (arg == "-diff") {
+ i++;
+ if (i < argc) {
+ diff = atoi(argv[i]);
+ i++;
+ }
+ }
+ else {
+ usage();
+ }
+ }
+ if (nums.empty() || diff < 0)
+ usage();
+
+ // process
+ int count = count_triplets(nums, diff);
+ cout << count << endl;
+}
diff --git a/challenge-241/paulo-custodio/cpp/ch-2.cpp b/challenge-241/paulo-custodio/cpp/ch-2.cpp
new file mode 100644
index 0000000000..c6bee319f8
--- /dev/null
+++ b/challenge-241/paulo-custodio/cpp/ch-2.cpp
@@ -0,0 +1,120 @@
+/*
+Challenge 241
+
+Task 2: Prime Order
+Submitted by: Mohammad S Anwar
+
+You are given an array of unique positive integers greater than 2.
+
+Write a script to sort them in ascending order of the count of their prime
+factors, tie-breaking by ascending value.
+Example 1
+
+Input: @int = (11, 8, 27, 4)
+Output: (11, 4, 8, 27))
+
+Prime factors of 11 => 11
+Prime factors of 4 => 2, 2
+Prime factors of 8 => 2, 2, 2
+Prime factors of 27 => 3, 3, 3
+*/
+
+#include <algorithm>
+#include <iostream>
+#include <vector>
+using namespace std;
+
+struct Num {
+ int n;
+ vector<int> factors;
+
+ Num(int n);
+ bool operator<(const Num& other);
+};
+
+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;
+}
+
+vector<int> prime_factors(int n) {
+ vector<int> out;
+ if (n < 2) {
+ int p = 1;
+ out.push_back(p);
+ }
+ else {
+ int p = 2;
+ while (n > 1) {
+ while (n % p == 0) {
+ out.push_back(p);
+ n /= p;
+ }
+ p = next_prime(p);
+ }
+ }
+ return out;
+}
+
+Num::Num(int n) {
+ this->n = n;
+ this->factors = prime_factors(n);
+}
+
+int num_compare(const Num& a, const Num& b) {
+ int a_size = static_cast<int>(a.factors.size());
+ int b_size = static_cast<int>(b.factors.size());
+ if (a_size != b_size)
+ return a_size - b_size;
+ for (size_t i = 0; i < a_size; i++) {
+ if (a.factors[i] != b.factors[i])
+ return a.factors[i] - b.factors[i];
+ }
+ return 0;
+}
+
+bool Num::operator<(const Num& other) {
+ return num_compare(*this, other) < 0 ? true : false;
+}
+
+int main(int argc, char* argv[]) {
+ if (argc < 2) {
+ cerr << "Usage: ch-2 n n n ..." << endl;
+ exit(EXIT_FAILURE);
+ }
+
+ vector<Num> nums;
+
+ // parse args and compute primes
+ for (int i = 1; i < argc; i++) {
+ int n = atoi(argv[i]);
+ nums.emplace_back(n);
+ }
+
+ // sort
+ sort(nums.begin(), nums.end());
+
+ // output
+ const char* sep = "";
+ for (auto& num : nums) {
+ cout << sep << num.n;
+ sep = " ";
+ }
+}
diff --git a/challenge-241/paulo-custodio/perl/ch-1.pl b/challenge-241/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..407c471494
--- /dev/null
+++ b/challenge-241/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,71 @@
+#!/usr/bin/env perl
+
+# Challenge 241
+#
+# Task 1: Arithmetic Triplets
+# Submitted by: Mohammad S Anwar
+#
+# You are given an array (3 or more members) of integers in increasing order
+# and a positive integer.
+#
+# Write a script to find out the number of unique Arithmetic Triplets satisfying
+# the following rules:
+#
+# a) i < j < k
+# b) nums[j] - nums[i] == diff
+# c) nums[k] - nums[j] == diff
+#
+# Example 1
+#
+# Input: @nums = (0, 1, 4, 6, 7, 10)
+# $diff = 3
+# Output: 2
+#
+# Index (1, 2, 4) is an arithmetic triplet because both 7 - 4 == 3 and 4 - 1 == 3.
+# Index (2, 4, 5) is an arithmetic triplet because both 10 - 7 == 3 and 7 - 4 == 3.
+#
+# Example 2
+#
+# Input: @nums = (4, 5, 6, 7, 8, 9)
+# $diff = 2
+# Output: 2
+#
+# (0, 2, 4) is an arithmetic triplet because both 8 - 6 == 2 and 6 - 4 == 2.
+# (1, 3, 5) is an arithmetic triplet because both 9 - 7 == 2 and 7 - 5 == 2.
+
+use Modern::Perl;
+
+# parse args
+sub usage { return "Usage: $0 -nums n n n ... -diff n\n"; }
+
+my(@nums, $diff);
+while (@ARGV) {
+ if ($ARGV[0] eq "-nums") {
+ shift;
+ while (@ARGV && $ARGV[0] !~ /^-/) {
+ push @nums, shift;
+ }
+ }
+ elsif ($ARGV[0] eq "-diff") {
+ shift;
+ $diff = shift;
+ }
+ else {
+ die usage();
+ }
+}
+if (!@nums || !$diff) { die usage(); }
+
+# compute
+my $count = 0;
+for my $i (0 .. $#nums-2) {
+ for my $j ($i+1 .. $#nums-1) {
+ for my $k ($j+1 .. $#nums) {
+ $count++ if ($nums[$j] - $nums[$i] == $diff &&
+ $nums[$k] - $nums[$j] == $diff);
+ }
+ }
+}
+
+# output
+say $count;
diff --git a/challenge-241/paulo-custodio/perl/ch-2.pl b/challenge-241/paulo-custodio/perl/ch-2.pl
new file mode 100644
index 0000000000..8c598ef885
--- /dev/null
+++ b/challenge-241/paulo-custodio/perl/ch-2.pl
@@ -0,0 +1,67 @@
+#!/usr/bin/env perl
+
+# Challenge 241
+#
+# Task 2: Prime Order
+# Submitted by: Mohammad S Anwar
+#
+# You are given an array of unique positive integers greater than 2.
+#
+# Write a script to sort them in ascending order of the count of their prime
+# factors, tie-breaking by ascending value.
+# Example 1
+#
+# Input: @int = (11, 8, 27, 4)
+# Output: (11, 4, 8, 27))
+#
+# Prime factors of 11 => 11
+# Prime factors of 4 => 2, 2
+# Prime factors of 8 => 2, 2, 2
+# Prime factors of 27 => 3, 3, 3
+
+use Modern::Perl;
+
+sub is_prime {
+ my($n) = @_;
+ return 0 if $n <= 1;
+ return 1 if $n <= 3;
+ return 0 if ($n % 2)==0 || ($n % 3)==0;
+ for (my $i = 5; $i*$i <= $n; $i += 6) {
+ return 0 if ($n % $i)==0 || ($n % ($i+2))==0;
+ }
+ return 1;
+}
+
+sub prime_factors {
+ my($n) = @_;
+ my @factors;
+ my $p = 0;
+ while ($n > 1) {
+ do { $p++; } while (!is_prime($p));
+ while ($n % $p == 0) {
+ push @factors, $p;
+ $n /= $p;
+ }
+ }
+ return @factors;
+}
+
+# parse args
+@ARGV>0 or die "ch-2 n n...\n";
+my @nums = @ARGV;
+
+# process
+@nums = map { $_->[0] }
+ sort {
+ my(@fa) = @{$a->[1]};
+ my(@fb) = @{$b->[1]};
+ if (@fa != @fb) { return scalar(@fa) - scalar(@fb); }
+ for my $i (0 .. $#fa) {
+ if ($fa[$i] != $fb[$i]) { return $fa[$i] - $fb[$i]; }
+ }
+ return 0;
+ }
+ map {[$_, [prime_factors($_)]]} @nums;
+
+# output
+say "@nums";
diff --git a/challenge-241/paulo-custodio/t/test-1.yaml b/challenge-241/paulo-custodio/t/test-1.yaml
new file mode 100644
index 0000000000..b4593c8ed1
--- /dev/null
+++ b/challenge-241/paulo-custodio/t/test-1.yaml
@@ -0,0 +1,10 @@
+- setup:
+ cleanup:
+ args: -nums 0 1 4 6 7 10 -diff 3
+ input:
+ output: 2
+- setup:
+ cleanup:
+ args: -nums 4 5 6 7 8 9 -diff 2
+ input:
+ output: 2
diff --git a/challenge-241/paulo-custodio/t/test-2.yaml b/challenge-241/paulo-custodio/t/test-2.yaml
new file mode 100644
index 0000000000..2f50da7c69
--- /dev/null
+++ b/challenge-241/paulo-custodio/t/test-2.yaml
@@ -0,0 +1,10 @@
+- setup:
+ cleanup:
+ args: 11 8 27 4
+ input:
+ output: 11 4 8 27
+- setup:
+ cleanup:
+ args: 11 27 8 4
+ input:
+ output: 11 4 8 27