diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2023-03-26 10:43:58 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-26 10:43:58 +0100 |
| commit | b023909c82c6bb008d6cfa2239b4ffaf976fc9c0 (patch) | |
| tree | 0aa036ce7125051228e7b8cae23551cf9daa38f7 /challenge-209 | |
| parent | 3c907b5d42ebde85cb3ee174b68cdd0f6da2e8e2 (diff) | |
| parent | 05c416dd8e744f4c761d49ef5a0a720eb8198e90 (diff) | |
| download | perlweeklychallenge-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/Makefile | 2 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/basic/ch-1.bas | 54 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/basic/ch-2.bas | 140 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/c/ch-1.c | 69 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/c/ch-2.c | 216 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/cpp/ch-1.cpp | 66 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/cpp/ch-2.cpp | 101 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/forth/ch-1.fs | 92 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/forth/ch-2.fs | 237 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/perl/ch-1.pl | 52 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/perl/ch-2.pl | 89 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/t/test-1.yaml | 10 | ||||
| -rw-r--r-- | challenge-209/paulo-custodio/t/test-2.yaml | 15 |
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] -> |
