aboutsummaryrefslogtreecommitdiff
path: root/challenge-209
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2023-03-26 10:43:58 +0100
committerGitHub <noreply@github.com>2023-03-26 10:43:58 +0100
commitb023909c82c6bb008d6cfa2239b4ffaf976fc9c0 (patch)
tree0aa036ce7125051228e7b8cae23551cf9daa38f7 /challenge-209
parent3c907b5d42ebde85cb3ee174b68cdd0f6da2e8e2 (diff)
parent05c416dd8e744f4c761d49ef5a0a720eb8198e90 (diff)
downloadperlweeklychallenge-club-b023909c82c6bb008d6cfa2239b4ffaf976fc9c0.tar.gz
perlweeklychallenge-club-b023909c82c6bb008d6cfa2239b4ffaf976fc9c0.tar.bz2
perlweeklychallenge-club-b023909c82c6bb008d6cfa2239b4ffaf976fc9c0.zip
Merge pull request #7782 from pauloscustodio/master
Add Perl, C, C++, BASIC and Forth solutions
Diffstat (limited to 'challenge-209')
-rw-r--r--challenge-209/paulo-custodio/Makefile2
-rw-r--r--challenge-209/paulo-custodio/basic/ch-1.bas54
-rw-r--r--challenge-209/paulo-custodio/basic/ch-2.bas140
-rw-r--r--challenge-209/paulo-custodio/c/ch-1.c69
-rw-r--r--challenge-209/paulo-custodio/c/ch-2.c216
-rw-r--r--challenge-209/paulo-custodio/cpp/ch-1.cpp66
-rw-r--r--challenge-209/paulo-custodio/cpp/ch-2.cpp101
-rw-r--r--challenge-209/paulo-custodio/forth/ch-1.fs92
-rw-r--r--challenge-209/paulo-custodio/forth/ch-2.fs237
-rw-r--r--challenge-209/paulo-custodio/perl/ch-1.pl52
-rw-r--r--challenge-209/paulo-custodio/perl/ch-2.pl89
-rw-r--r--challenge-209/paulo-custodio/t/test-1.yaml10
-rw-r--r--challenge-209/paulo-custodio/t/test-2.yaml15
13 files changed, 1143 insertions, 0 deletions
diff --git a/challenge-209/paulo-custodio/Makefile b/challenge-209/paulo-custodio/Makefile
new file mode 100644
index 0000000000..c3c762d746
--- /dev/null
+++ b/challenge-209/paulo-custodio/Makefile
@@ -0,0 +1,2 @@
+all:
+ perl ../../challenge-001/paulo-custodio/test.pl
diff --git a/challenge-209/paulo-custodio/basic/ch-1.bas b/challenge-209/paulo-custodio/basic/ch-1.bas
new file mode 100644
index 0000000000..f3b1c1013f
--- /dev/null
+++ b/challenge-209/paulo-custodio/basic/ch-1.bas
@@ -0,0 +1,54 @@
+' Challenge 209
+'
+' Task 1: Special Bit Characters
+' Submitted by: Mohammad S Anwar
+'
+' You are given an array of binary bits that ends with 0.
+'
+' Valid sequences in the bit string are:
+'
+' [0] -decodes-to-> "a"
+' [1, 0] -> "b"
+' [1, 1] -> "c"
+'
+' Write a script to print 1 if the last character is an “a” otherwise print 0.
+' Example 1
+'
+' Input: @bits = (1, 0, 0)
+' Output: 1
+'
+' The given array bits can be decoded as 2-bits character (10) followed by
+' 1-bit character (0).
+'
+' Example 2
+'
+' Input: @bits = (1, 1, 1, 0)
+' Output: 0
+'
+' Possible decode can be 2-bits character (11) followed by 2-bits character
+' (10) i.e. the last character is not 1-bit character.
+
+function decode(in as string) as string
+ dim result as string
+ do while in<>""
+ if left(in,1)="0" then
+ result=result+"a"
+ in=mid(in,2)
+ elseif left(in,2)="10" then
+ result=result+"b"
+ in=mid(in,3)
+ elseif left(in,2)="11" then
+ result=result+"c"
+ in=mid(in,3)
+ else
+ print "Error: cannot parse: "; in
+ end
+ end if
+ loop
+ decode=result
+end function
+
+dim in as string, result as string
+in=command(1)
+result=decode(in)
+if right(result,1)="a" then print 1: else print 0
diff --git a/challenge-209/paulo-custodio/basic/ch-2.bas b/challenge-209/paulo-custodio/basic/ch-2.bas
new file mode 100644
index 0000000000..02e2fb621f
--- /dev/null
+++ b/challenge-209/paulo-custodio/basic/ch-2.bas
@@ -0,0 +1,140 @@
+' Challenge 209
+'
+' Task 2: Merge Account
+' Submitted by: Mohammad S Anwar
+'
+' You are given an array of accounts i.e. name with list of email addresses.
+'
+' Write a script to merge the accounts where possible. The accounts can only
+' be merged if they have at least one email address in common.
+'
+' Example 1:
+'
+' Input: @accounts = [ ["A", "a1@a.com", "a2@a.com"],
+' ["B", "b1@b.com"],
+' ["A", "a3@a.com", "a1@a.com"] ]
+' ]
+'
+' Output: [ ["A", "a1@a.com", "a2@a.com", "a3@a.com"],
+' ["B", "b1@b.com"] ]
+'
+' Example 2:
+'
+' Input: @accounts = [ ["A", "a1@a.com", "a2@a.com"],
+' ["B", "b1@b.com"],
+' ["A", "a3@a.com"],
+' ["B", "b2@b.com", "b1@b.com"] ]
+'
+' Output: [ ["A", "a1@a.com", "a2@a.com"],
+' ["A", "a3@a.com"],
+' ["B", "b1@b.com", "b2@b.com"] ]
+
+dim shared names() as string
+dim shared emails() as string
+
+sub collect_args()
+ dim i as integer, j as integer, row as integer
+ row=1
+ i=1
+ do while command(i)<>""
+ redim preserve names(row) as string
+ redim preserve emails(row) as string
+ names(row)=command(i)
+ i=i+1
+ do while command(i)<>"" and command(i)<>","
+ emails(row)=emails(row)+command(i)+" "
+ i=i+1
+ loop
+ if command(i)="," then i=i+1: row=row+1
+ loop
+end sub
+
+sub split(byval text as string, delim as string = " ", ret() as string)
+ dim p as integer, count as integer
+ count=0
+ do
+ do while left(text,1)=delim: text=mid(text,2): loop ' eat front delimiters
+ if text="" then exit do
+ redim preserve ret(count) as string
+ p=instr(text,delim)
+ if p<1 then
+ ret(count)=text
+ exit do
+ else
+ ret(count)=left(text,p-1)
+ text=mid(text,p+1)
+ count=count+1
+ end if
+ loop
+end sub
+
+function common_email(byref aa as integer, byref bb as integer) as boolean
+ dim emails_a() as string, emails_b() as string
+ dim a as integer, i as integer, b as integer, j as integer
+ for a=0 to ubound(names)
+ split(emails(a),,emails_a())
+ for i=0 to ubound(emails_a)
+ for b=0 to ubound(names)
+ if a<>b then
+ split(emails(b),,emails_b())
+ for j=0 to ubound(emails_b)
+ if emails_a(i)=emails_b(j) then
+ aa=a: bb=b: common_email=true
+ exit function
+ end if
+ next
+ end if
+ next
+ next
+ next
+ common_email=false
+end function
+
+sub sort(s() as string)
+ dim i as integer, j as integer, tmp as string
+ for i=0 to ubound(s)-1
+ for j=i+1 to ubound(s)
+ if s(i)>s(j) then tmp=s(i): s(i)=s(j): s(j)=tmp
+ next
+ next
+end sub
+
+function sort_uniq_emails(emails as string) as string
+ dim s() as string, i as integer, last as string, ret as string
+ split emails,,s()
+ sort s()
+ ret=""
+ for i=0 to ubound(s)
+ if s(i)<>last then
+ ret=ret+s(i)+" "
+ last=s(i)
+ end if
+ next
+ sort_uniq_emails=ret
+end function
+
+sub merge_account(a as integer, b as integer)
+ dim all_emails as string, i as integer
+ all_emails=sort_uniq_emails(emails(a)+" "+emails(b))
+ emails(a)=all_emails
+ for i=b to ubound(names)-1
+ names(i)=names(i+1)
+ emails(i)=emails(i+1)
+ next
+ redim preserve names(ubound(names)-1)
+ redim preserve emails(ubound(emails)-1)
+end sub
+
+sub merge_accounts()
+ dim a as integer, b as integer
+ do while common_email(a, b)
+ merge_account(a, b)
+ loop
+end sub
+
+dim i as integer
+collect_args
+merge_accounts
+for i=0 to ubound(names)
+ print names(i);" ";emails(i)
+next
diff --git a/challenge-209/paulo-custodio/c/ch-1.c b/challenge-209/paulo-custodio/c/ch-1.c
new file mode 100644
index 0000000000..370f5f0399
--- /dev/null
+++ b/challenge-209/paulo-custodio/c/ch-1.c
@@ -0,0 +1,69 @@
+/*
+Challenge 209
+
+Task 1: Special Bit Characters
+Submitted by: Mohammad S Anwar
+
+You are given an array of binary bits that ends with 0.
+
+Valid sequences in the bit string are:
+
+[0] -decodes-to-> "a"
+[1, 0] -> "b"
+[1, 1] -> "c"
+
+Write a script to print 1 if the last character is an “a” otherwise print 0.
+Example 1
+
+Input: @bits = (1, 0, 0)
+Output: 1
+
+The given array bits can be decoded as 2-bits character (10) followed by
+1-bit character (0).
+
+Example 2
+
+Input: @bits = (1, 1, 1, 0)
+Output: 0
+
+Possible decode can be 2-bits character (11) followed by 2-bits character
+(10) i.e. the last character is not 1-bit character.
+*/
+
+#define MAX_STRING 256
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void decode(char* out, const char* in) {
+ const char* p = in;
+ char* q = out;
+ while (*p) {
+ switch (*p) {
+ case '0': *q++ = 'a'; p++; break;
+ case '1':
+ p++;
+ switch (*p) {
+ case '0': *q++ = 'b'; p++; break;
+ case '1': *q++ = 'c'; p++; break;
+ default: fputs("invalid input", stderr); exit(EXIT_FAILURE);
+ }
+ break;
+ default: fputs("invalid input", stderr); exit(EXIT_FAILURE);
+ }
+ }
+ *q++ = '\0';
+}
+
+int main(int argc, char* argv[]) {
+ argv++; argc--;
+ if (argc != 1) {
+ fputs("usage: ch-2 str\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ char out[MAX_STRING];
+ decode(out, argv[0]);
+ printf("%d\n", out[strlen(out)-1] == 'a' ? 1 : 0);
+}
diff --git a/challenge-209/paulo-custodio/c/ch-2.c b/challenge-209/paulo-custodio/c/ch-2.c
new file mode 100644
index 0000000000..b961ebb60c
--- /dev/null
+++ b/challenge-209/paulo-custodio/c/ch-2.c
@@ -0,0 +1,216 @@
+/*
+Challenge 209
+
+Task 2: Merge Account
+Submitted by: Mohammad S Anwar
+
+You are given an array of accounts i.e. name with list of email addresses.
+
+Write a script to merge the accounts where possible. The accounts can only
+be merged if they have at least one email address in common.
+
+Example 1:
+
+Input: @accounts = [ ["A", "a1@a.com", "a2@a.com"],
+ ["B", "b1@b.com"],
+ ["A", "a3@a.com", "a1@a.com"] ]
+ ]
+
+Output: [ ["A", "a1@a.com", "a2@a.com", "a3@a.com"],
+ ["B", "b1@b.com"] ]
+
+Example 2:
+
+Input: @accounts = [ ["A", "a1@a.com", "a2@a.com"],
+ ["B", "b1@b.com"],
+ ["A", "a3@a.com"],
+ ["B", "b2@b.com", "b1@b.com"] ]
+
+Output: [ ["A", "a1@a.com", "a2@a.com"],
+ ["A", "a3@a.com"],
+ ["B", "b1@b.com", "b2@b.com"] ]
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+typedef struct ArrayStr {
+ int count;
+ char** items;
+} ArrayStr;
+
+typedef struct Account {
+ char* name;
+ ArrayStr* emails;
+} Account;
+
+typedef struct Accounts {
+ int count;
+ Account** items;
+} Accounts;
+
+void* check_mem(void* p) {
+ if (!p) {
+ fputs("Out of memory", stderr);
+ exit(EXIT_FAILURE);
+ }
+ return p;
+}
+
+ArrayStr* arrstr_new() {
+ return check_mem(calloc(1, sizeof(ArrayStr)));
+}
+
+void arrstr_clear(ArrayStr* as) {
+ for (int i = 0; i < as->count; i++)
+ free(as->items[i]);
+ as->count = 0;
+}
+
+void arrstr_free(ArrayStr* as) {
+ arrstr_clear(as);
+ free(as);
+}
+
+void arrstr_push(ArrayStr* as, const char* s) {
+ as->items = check_mem(realloc(as->items, (as->count + 1) * sizeof(char**)));
+ as->items[as->count++] = check_mem(strdup(s));
+}
+
+void arrstr_remove(ArrayStr* as, int idx) {
+ if (idx < as->count) {
+ free(as->items[idx]);
+ memmove(&as->items[idx], &as->items[idx + 1], (as->count - idx - 1) * sizeof(char**));
+ as->count--;
+ }
+}
+
+int compare(const void* a, const void* b) {
+ return strcmp(*(const char**)a, *(const char**)b);
+}
+
+void arrstr_sort(ArrayStr* as) {
+ qsort(as->items, as->count, sizeof(char**), compare);
+}
+
+void arrstr_uniq(ArrayStr* as) {
+ arrstr_sort(as);
+ for (int i = 0; i < as->count - 1; i++) {
+ if (strcmp(as->items[i], as->items[i + 1]) == 0) {
+ arrstr_remove(as, i + 1);
+ i--;
+ }
+ }
+}
+
+int arrstr_find(ArrayStr* as, const char* name) {
+ for (int i = 0; i < as->count; i++)
+ if (strcmp(as->items[i], name) == 0)
+ return i;
+ return -1;
+}
+
+Account* acc_new(const char* name) {
+ Account* acc = check_mem(calloc(1, sizeof(Account)));
+ acc->name = check_mem(strdup(name));
+ acc->emails = arrstr_new();
+ return acc;
+}
+
+void acc_free(Account* acc) {
+ free(acc->name);
+ arrstr_free(acc->emails);
+ free(acc);
+}
+
+void acc_push_email(Account* acc, const char* email) {
+ arrstr_push(acc->emails, email);
+}
+
+void acc_merge(Account* acc, Account* other) {
+ for (int i = 0; i < other->emails->count; i++)
+ acc_push_email(acc, other->emails->items[i]);
+ arrstr_uniq(acc->emails);
+}
+
+Accounts* accs_new() {
+ return check_mem(calloc(1, sizeof(Accounts)));
+}
+
+void accs_clear(Accounts* accs) {
+ for (int i = 0; i < accs->count; i++)
+ acc_free(accs->items[i]);
+ accs->count = 0;
+}
+
+void accs_free(Accounts* accs) {
+ accs_clear(accs);
+ free(accs);
+}
+
+void accs_push(Accounts* accs, const char* name) {
+ accs->items = check_mem(realloc(accs->items, (accs->count + 1) * sizeof(Account**)));
+ accs->items[accs->count++] = acc_new(name);
+}
+
+void accs_remove(Accounts* accs, int idx) {
+ if (idx < accs->count) {
+ acc_free(accs->items[idx]);
+ memmove(&accs->items[idx], &accs->items[idx + 1], (accs->count - idx - 1) * sizeof(Account**));
+ accs->count--;
+ }
+}
+
+bool accs_find_common(Accounts* accs, int* pa, int* pb) {
+ for (*pa = 0; *pa < accs->count - 1; (*pa)++) {
+ for (int i = 0; i < accs->items[*pa]->emails->count; i++) {
+ const char* email = accs->items[*pa]->emails->items[i];
+ for (*pb = *pa + 1; *pb < accs->count; (*pb)++) {
+ if (arrstr_find(accs->items[*pb]->emails, email) >= 0) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void accs_merge(Accounts* accs) {
+ int a, b;
+ while (accs_find_common(accs, &a, &b)) {
+ acc_merge(accs->items[a], accs->items[b]);
+ accs_remove(accs, b);
+ }
+}
+
+int main(int argc, char* argv[]) {
+ argv++; argc--;
+ if (argc == 0) {
+ fputs("usage: ch-2 name emails... name emails...\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ Accounts* accs = accs_new();
+
+ for (int i = 0; i < argc; i++) {
+ const char* name = argv[i++];
+ accs_push(accs, name);
+ for (; i < argc && strcmp(argv[i], ",") != 0; i++) {
+ const char* email = argv[i];
+ acc_push_email(accs->items[accs->count - 1], email);
+ }
+ }
+
+ accs_merge(accs);
+
+ for (int i = 0; i < accs->count; i++) {
+ printf("%s ", accs->items[i]->name);
+ for (int j = 0; j < accs->items[i]->emails->count; j++)
+ printf("%s ", accs->items[i]->emails->items[j]);
+ printf("\n");
+ }
+
+ accs_free(accs);
+}
diff --git a/challenge-209/paulo-custodio/cpp/ch-1.cpp b/challenge-209/paulo-custodio/cpp/ch-1.cpp
new file mode 100644
index 0000000000..af0e604c5e
--- /dev/null
+++ b/challenge-209/paulo-custodio/cpp/ch-1.cpp
@@ -0,0 +1,66 @@
+/*
+Challenge 209
+
+Task 1: Special Bit Characters
+Submitted by: Mohammad S Anwar
+
+You are given an array of binary bits that ends with 0.
+
+Valid sequences in the bit string are:
+
+[0] -decodes-to-> "a"
+[1, 0] -> "b"
+[1, 1] -> "c"
+
+Write a script to print 1 if the last character is an “a” otherwise print 0.
+Example 1
+
+Input: @bits = (1, 0, 0)
+Output: 1
+
+The given array bits can be decoded as 2-bits character (10) followed by
+1-bit character (0).
+
+Example 2
+
+Input: @bits = (1, 1, 1, 0)
+Output: 0
+
+Possible decode can be 2-bits character (11) followed by 2-bits character
+(10) i.e. the last character is not 1-bit character.
+*/
+
+#include <iostream>
+#include <string>
+
+std::string decode(const std::string& in) {
+ std::string out;
+ const char* p = in.c_str();
+ while (*p) {
+ switch (*p) {
+ case '0': out.push_back('a'); p++; break;
+ case '1':
+ p++;
+ switch (*p) {
+ case '0': out.push_back('b'); p++; break;
+ case '1': out.push_back('c'); p++; break;
+ default: std::cerr << "invalid input" << std::endl; exit(EXIT_FAILURE);
+ }
+ break;
+ default: std::cerr << "invalid input" << std::endl; exit(EXIT_FAILURE);
+ }
+ }
+ return out;
+}
+
+int main(int argc, char* argv[]) {
+ argv++; argc--;
+ if (argc != 1) {
+ std::cerr << "usage: ch-2 str" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ std::string out = decode(argv[0]);
+ int result = (!out.empty() && out.back()=='a') ? 1 : 0;
+ std::cout << result << std::endl;
+}
diff --git a/challenge-209/paulo-custodio/cpp/ch-2.cpp b/challenge-209/paulo-custodio/cpp/ch-2.cpp
new file mode 100644
index 0000000000..1b9ef82fd7
--- /dev/null
+++ b/challenge-209/paulo-custodio/cpp/ch-2.cpp
@@ -0,0 +1,101 @@
+/*
+Challenge 209
+
+Task 2: Merge Account
+Submitted by: Mohammad S Anwar
+
+You are given an array of accounts i.e. name with list of email addresses.
+
+Write a script to merge the accounts where possible. The accounts can only
+be merged if they have at least one email address in common.
+
+Example 1:
+
+Input: @accounts = [ ["A", "a1@a.com", "a2@a.com"],
+ ["B", "b1@b.com"],
+ ["A", "a3@a.com", "a1@a.com"] ]
+ ]
+
+Output: [ ["A", "a1@a.com", "a2@a.com", "a3@a.com"],
+ ["B", "b1@b.com"] ]
+
+Example 2:
+
+Input: @accounts = [ ["A", "a1@a.com", "a2@a.com"],
+ ["B", "b1@b.com"],
+ ["A", "a3@a.com"],
+ ["B", "b2@b.com", "b1@b.com"] ]
+
+Output: [ ["A", "a1@a.com", "a2@a.com"],
+ ["A", "a3@a.com"],
+ ["B", "b1@b.com", "b2@b.com"] ]
+*/
+
+#include <algorithm>
+#include <iostream>
+#include <string>
+#include <vector>
+
+struct Account {
+ std::string name;
+ std::vector<std::string> emails;
+
+ Account(const std::string& name_) : name(name_) {}
+
+ void merge(const Account& other) {
+ emails.insert(emails.end(), other.emails.begin(), other.emails.end()); // concatenate
+ std::sort(emails.begin(), emails.end()); // sort
+ auto it = std::unique(emails.begin(), emails.end()); // uniq
+ emails.resize(std::distance(emails.begin(), it));
+ }
+};
+
+bool find_common(std::vector<Account>& accs, size_t& a, size_t& b) {
+ for (a = 0; a < accs.size() - 1; a++) {
+ for (size_t i = 0; i < accs[a].emails.size(); i++) {
+ std::string& email = accs[a].emails[i];
+ for (b = a + 1; b < accs.size(); b++) {
+ auto it = std::find(accs[b].emails.begin(), accs[b].emails.end(), email);
+ if (it != accs[b].emails.end())
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void merge_accounts(std::vector<Account>& accs) {
+ size_t a, b;
+ while (find_common(accs, a, b)) {
+ accs[a].merge(accs[b]);
+ accs.erase(accs.begin() + b);
+ }
+}
+
+int main(int argc, char* argv[]) {
+ argv++; argc--;
+ if (argc == 0) {
+ std::cerr << "usage: ch-2 name emails... name emails..." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ std::vector<Account> accs;
+
+ for (int i = 0; i < argc; i++) {
+ std::string name = argv[i++];
+ accs.emplace_back(name);
+ for (; i < argc && std::string(argv[i])!= ","; i++) {
+ std::string email = argv[i];
+ accs.back().emails.push_back(email);
+ }
+ }
+
+ merge_accounts(accs);
+
+ for (size_t i = 0; i < accs.size(); i++) {
+ std::cout << accs[i].name << " ";
+ for (size_t j = 0; j < accs[i].emails.size(); j++)
+ std::cout << accs[i].emails[j] << " ";
+ std::cout << std::endl;
+ }
+}
diff --git a/challenge-209/paulo-custodio/forth/ch-1.fs b/challenge-209/paulo-custodio/forth/ch-1.fs
new file mode 100644
index 0000000000..f79b5367df
--- /dev/null
+++ b/challenge-209/paulo-custodio/forth/ch-1.fs
@@ -0,0 +1,92 @@
+#! /usr/bin/env gforth
+
+\ Challenge 209
+\
+\ Task 1: Special Bit Characters
+\ Submitted by: Mohammad S Anwar
+\
+\ You are given an array of binary bits that ends with 0.
+\
+\ Valid sequences in the bit string are:
+\
+\ [0] -decodes-to-> "a"
+\ [1, 0] -> "b"
+\ [1, 1] -> "c"
+\
+\ Write a script to print 1 if the last character is an “a” otherwise print 0.
+\ Example 1
+\
+\ Input: @bits = (1, 0, 0)
+\ Output: 1
+\
+\ The given array bits can be decoded as 2-bits character (10) followed by
+\ 1-bit character (0).
+\
+\ Example 2
+\
+\ Input: @bits = (1, 1, 1, 0)
+\ Output: 0
+\
+\ Possible decode can be 2-bits character (11) followed by 2-bits character
+\ (10) i.e. the last character is not 1-bit character.
+
+\ line of decoded text
+CREATE output 0 C, 255 ALLOT
+0 VALUE last_output_is_a
+
+: append_output ( ch -- )
+ DUP 'a' = IF 1 TO last_output_is_a ELSE 0 TO last_output_is_a THEN
+ output COUNT + C!
+ output C@ 1+ output C!
+;
+
+: append_a 'a' append_output ;
+: append_b 'b' append_output ;
+: append_c 'c' append_output ;
+
+CREATE input 256 ALLOT
+
+: set_input { addr len -- }
+ 1 input C! \ next char pointer
+ addr input 1+ len CMOVE
+ 0 input 1+ len + C! \ end marker
+;
+
+: cur_input ( -- ch|0 )
+ input C@ input + C@
+;
+
+: next_input ( -- ch|0 )
+ cur_input 0<> IF
+ input C@ 1+ input C!
+ THEN
+ cur_input
+;
+
+: skip_input ( -- )
+ next_input DROP
+;
+
+: decode_str ( -- )
+ 0 { decode_state }
+ BEGIN
+ decode_state 0= IF
+ cur_input 0= IF EXIT ELSE
+ cur_input '0' = IF append_a skip_input ELSE
+ cur_input '1' = IF 1 TO decode_state skip_input ELSE
+ EXIT
+ THEN THEN THEN
+ ELSE
+ cur_input 0= IF EXIT ELSE
+ cur_input '0' = IF append_b skip_input 0 TO decode_state ELSE
+ cur_input '1' = IF append_c skip_input 0 TO decode_state ELSE
+ EXIT
+ THEN THEN THEN
+ THEN
+ AGAIN
+;
+
+NEXT-ARG set_input
+decode_str
+last_output_is_a . CR
+BYE
diff --git a/challenge-209/paulo-custodio/forth/ch-2.fs b/challenge-209/paulo-custodio/forth/ch-2.fs
new file mode 100644
index 0000000000..b21756d539
--- /dev/null
+++ b/challenge-209/paulo-custodio/forth/ch-2.fs
@@ -0,0 +1,237 @@
+#! /usr/bin/env gforth
+
+\ Challenge 209
+\
+\ Task 2: Merge Account
+\ Submitted by: Mohammad S Anwar
+\
+\ You are given an array of accounts i.e. name with list of email addresses.
+\
+\ Write a script to merge the accounts where possible. The accounts can only
+\ be merged if they have at least one email address in common.
+\
+\ Example 1:
+\
+\ Input: @accounts = [ ["A", "a1@a.com", "a2@a.com"],
+\ ["B", "b1@b.com"],
+\ ["A", "a3@a.com", "a1@a.com"] ]
+\ ]
+\
+\ Output: [ ["A", "a1@a.com", "a2@a.com", "a3@a.com"],
+\ ["B", "b1@b.com"] ]
+\
+\ Example 2:
+\
+\ Input: @accounts = [ ["A", "a1@a.com", "a2@a.com"],
+\ ["B", "b1@b.com"],
+\ ["A", "a3@a.com"],
+\ ["B", "b2@b.com", "b1@b.com"] ]
+\
+\ Output: [ ["A", "a1@a.com", "a2@a.com"],
+\ ["A", "a3@a.com"],
+\ ["B", "b1@b.com", "b2@b.com"] ]
+
+\ mails list: word with length, dwords with each string pointer and length
+: emails_new ( -- lst )
+ CELL ALLOCATE THROW 0 OVER !
+;
+
+: emails_delete ( lst -- )
+ FREE THROW
+;
+
+: emails_size ( lst -- size )
+ @
+;
+
+: emails[] ( lst idx -- addr )
+ SWAP CELL + SWAP CELLS 2* +
+;
+
+: emails_resize ( lst size -- lst )
+ 2* CELLS CELL + RESIZE THROW
+;
+
+: emails_push { addr len lst -- lst }
+ lst lst emails_size 1+ emails_resize TO lst
+ addr len lst lst emails_size emails[] 2!
+ 1 lst +!
+ lst
+;
+
+: emails_type { lst -- }
+ lst emails_size 0 ?DO
+ lst I emails[] 2@ TYPE SPACE
+ LOOP
+;
+
+: emails_sort { lst -- }
+ lst emails_size 1 > IF
+ lst emails_size 1- 0 ?DO
+ lst emails_size I 1+ ?DO
+ lst J emails[] 2@
+ lst I emails[] 2@
+ 2OVER 2OVER
+ COMPARE 0> IF
+ lst J emails[] 2!
+ lst I emails[] 2!
+ ELSE
+ 2DROP 2DROP
+ THEN
+ LOOP
+ LOOP
+ THEN
+;
+
+: emails_uniq { lst -- }
+ lst emails_size 1 > IF
+ lst emails_sort
+ 0 { i }
+ BEGIN i lst emails_size 1- < WHILE
+ lst i emails[] 2@
+ lst i 1+ emails[] 2@
+ COMPARE 0= IF \ remove next entry
+ lst i 1+ emails[]
+ lst i emails[]
+ lst emails_size i - 1- CELLS 2*
+ MOVE
+ -1 lst +!
+ ELSE
+ i 1+ TO i
+ THEN
+ REPEAT
+ THEN
+;
+
+: emails_merge { lst1 lst2 -- lst1 }
+ lst2 emails_size 0 ?DO
+ lst2 I emails[] 2@
+ lst1 emails_push TO lst1
+ LOOP
+ lst1 emails_uniq
+ lst1
+;
+
+\ account: DCELL with name, CELL with emails
+: acc.name ( acc -- addr ) ;
+: acc.emails ( acc -- addr ) 2 CELLS + ;
+: acc.emails[] ( acc idx -- addr ) acc.emails emails[] ;
+
+: acc_new { name-addr len -- acc }
+ 3 CELLS ALLOCATE THROW { acc }
+ name-addr len acc acc.name 2!
+ emails_new acc acc.emails !
+ acc
+;
+
+: acc_delete { acc -- }
+ acc acc.emails @ emails_delete
+ acc FREE THROW
+;
+
+: acc.emails_push { addr len acc -- }
+ addr len acc acc.emails @ emails_push
+ acc acc.emails !
+;
+
+: acc_type { acc -- }
+ acc acc.name 2@ TYPE SPACE
+ acc acc.emails @ emails_type CR
+;
+
+: acc_merge { acc acc2 -- }
+ acc acc.emails @
+ acc2 acc.emails @
+ emails_merge
+ acc acc.emails !
+;
+
+\ accounts: CELL with count, CELLS with pointers to accounts
+: accs_new ( -- accs )
+ CELL ALLOCATE THROW
+ 0 OVER !
+;
+
+: accs_size ( accs -- size )
+ @
+;
+
+: accs[] ( accs idx -- addr )
+ SWAP CELL + SWAP CELLS +
+;
+
+: accs_resize ( accs size -- accs )
+ 1+ CELLS RESIZE THROW
+;
+
+: accs_push { addr-name len accs -- accs }
+ accs accs accs_size 1+ accs_resize TO accs
+ addr-name len acc_new
+ accs accs accs_size accs[] !
+ 1 accs +!
+ accs
+;
+
+: accs_type { accs -- }
+ accs accs_size 0 ?DO
+ accs I accs[] @ acc_type
+ LOOP
+;
+
+: collect_args ( -- accs )
+ accs_new { accs }
+ BEGIN NEXT-ARG DUP 0> WHILE
+ accs accs_push TO accs \ read name
+ BEGIN NEXT-ARG 2DUP S" ," COMPARE 0<> >R DUP 0<> R> AND WHILE
+ \ while not empty and not comma
+ accs accs accs_size 1- accs[] @ acc.emails_push
+ REPEAT
+ 2DROP
+ REPEAT
+ 2DROP
+ accs
+;
+
+: accs_find_common_email { accs -- a b t|f )
+ 0 0 FALSE { a b found }
+ BEGIN a accs accs_size 1- < WHILE
+ accs a accs[] @ acc.emails @ { emails }
+ emails emails_size 0 ?DO
+ emails I emails[] 2@ { email_addr email_len }
+ a 1+ TO b
+ BEGIN b accs accs_size < WHILE
+ accs b accs[] @ acc.emails @ { emails2 }
+ emails2 emails_size 0 ?DO
+ emails2 I emails[] 2@ { email2_addr email2_len }
+ email_addr email_len email2_addr email2_len
+ COMPARE 0= IF
+ a b TRUE TRUE to found LEAVE
+ THEN
+ LOOP
+ found IF leave THEN
+ b 1+ TO b
+ REPEAT
+ LOOP
+ found IF EXIT THEN
+ a 1+ TO a
+ REPEAT
+ FALSE
+;
+
+: accs_merge { accs -- }
+ BEGIN accs accs_find_common_email WHILE
+ { a b }
+ accs a accs[] @ acc.emails @ { a_emails }
+ accs b accs[] @ acc.emails @ { b_emails }
+ a_emails b_emails emails_merge { new_emails }
+ new_emails accs a accs[] @ acc.emails !
+ accs b accs[] @ acc_delete
+ accs b 1+ accs[] accs b accs[] accs accs_size b - 1+ CELLS MOVE
+ -1 accs +!
+ REPEAT
+;
+
+collect_args VALUE accs
+accs accs_merge
+accs accs_type
+BYE
diff --git a/challenge-209/paulo-custodio/perl/ch-1.pl b/challenge-209/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..15ed8e20b1
--- /dev/null
+++ b/challenge-209/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+
+# Challenge 209
+#
+# Task 1: Special Bit Characters
+# Submitted by: Mohammad S Anwar
+#
+# You are given an array of binary bits that ends with 0.
+#
+# Valid sequences in the bit string are:
+#
+# [0] -decodes-to-> "a"
+# [1, 0] ->