diff options
| author | Paulo Custodio <pauloscustodio@gmail.com> | 2023-03-16 14:27:11 +0000 |
|---|---|---|
| committer | Paulo Custodio <pauloscustodio@gmail.com> | 2023-03-16 14:27:11 +0000 |
| commit | 7d790f5488fbe8732f463abac59822d04f485f4c (patch) | |
| tree | 34e04c25fecca265537174b2cfd79ae47ae0eed8 | |
| parent | 4895c63c67294452dcf9fa4e8f3f47e4a3f1c39f (diff) | |
| download | perlweeklychallenge-club-7d790f5488fbe8732f463abac59822d04f485f4c.tar.gz perlweeklychallenge-club-7d790f5488fbe8732f463abac59822d04f485f4c.tar.bz2 perlweeklychallenge-club-7d790f5488fbe8732f463abac59822d04f485f4c.zip | |
Add C, C++, BASIC and Forth solutions
| -rw-r--r-- | challenge-208/paulo-custodio/basic/ch-1.bas | 90 | ||||
| -rw-r--r-- | challenge-208/paulo-custodio/basic/ch-2.bas | 70 | ||||
| -rw-r--r-- | challenge-208/paulo-custodio/c/ch-1.c | 131 | ||||
| -rw-r--r-- | challenge-208/paulo-custodio/c/ch-2.c | 93 | ||||
| -rw-r--r-- | challenge-208/paulo-custodio/cpp/ch-1.cpp | 95 | ||||
| -rw-r--r-- | challenge-208/paulo-custodio/cpp/ch-2.cpp | 82 | ||||
| -rw-r--r-- | challenge-208/paulo-custodio/forth/ch-1.fs | 131 | ||||
| -rw-r--r-- | challenge-208/paulo-custodio/forth/ch-2.fs | 83 | ||||
| -rw-r--r-- | challenge-208/paulo-custodio/perl/ch-1.pl | 2 |
9 files changed, 776 insertions, 1 deletions
diff --git a/challenge-208/paulo-custodio/basic/ch-1.bas b/challenge-208/paulo-custodio/basic/ch-1.bas new file mode 100644 index 0000000000..d95d4b8a92 --- /dev/null +++ b/challenge-208/paulo-custodio/basic/ch-1.bas @@ -0,0 +1,90 @@ +' Challenge 208 +' +' Task 1: Minimum Index Sum +' Submitted by: Mohammad S Anwar +' +' You are given two arrays of strings. +' +' Write a script to find out all common strings in the given two arrays with +' minimum index sum. If no common strings found returns an empty list. +' Example 1 +' +' Input: @list1 = ("Perl", "Raku", "Love") +' @list2 = ("Raku", "Perl", "Hate") +' +' Output: ("Perl", "Raku") +' +' There are two common strings "Perl" and "Raku". +' Index sum of "Perl": 0 + 1 = 1 +' Index sum of "Raku": 1 + 0 = 1 +' +' Example 2 +' +' Input: @list1 = ("A", "B", "C") +' @list2 = ("D", "E", "F") +' +' Output: () +' +' No common string found, so no result. +' +' Example 3 +' +' Input: @list1 = ("A", "B", "C") +' @list2 = ("C", "A", "B") +' +' Output: ("A") +' +' There are three common strings "A", "B" and "C". +' Index sum of "A": 0 + 1 = 1 +' Index sum of "B": 1 + 2 = 3 +' Index sum of "C": 2 + 0 = 2 + +sub collect_args(list1() as string, list2() as string) + dim args() as string, i as integer, n as integer + i=0 + do while command(i+1)<>"" + redim preserve args(i) + args(i)=command(i+1) + i=i+1 + loop + n=int((ubound(args)+1)/2) + redim list1(n-1) as string + redim list2(n-1) as string + for i=0 to n-1 + list1(i)=args(i) + list2(i)=args(n+i) + next +end sub + +sub common_strings(list1() as string, list2() as string, comm() as string) + dim i as integer, j as integer, min_index as integer, n as integer + erase comm + min_index=ubound(list1)+ubound(list2)+1 + for i=0 to ubound(list1) + for j=0 to ubound(list2) + if list1(i)=list2(j) then + if i+j<min_index then + redim preserve comm(0) as string + comm(0)=list1(i) + min_index=i+j + elseif i+j=min_index then + n=ubound(comm)+1 + redim preserve comm(n) as string + comm(n)=list1(i) + min_index=i+j + end if + end if + next + next +end sub + + + +dim list1() as string, list2() as string, comm() as string, i as integer +collect_args list1(), list2() +common_strings list1(), list2(), comm() +if ubound(comm)=-1 then + print "()" +else + for i=0 to ubound(comm): print comm(i);" ";: next: print +end if diff --git a/challenge-208/paulo-custodio/basic/ch-2.bas b/challenge-208/paulo-custodio/basic/ch-2.bas new file mode 100644 index 0000000000..7c2863888d --- /dev/null +++ b/challenge-208/paulo-custodio/basic/ch-2.bas @@ -0,0 +1,70 @@ +' Challenge 208 +' +' Task 2: Duplicate and Missing +' Submitted by: Mohammad S Anwar +' +' You are given an array of integers in sequence with one missing and one duplicate. +' +' Write a script to find the duplicate and missing integer in the given array. +' Return -1 if none found. +' +' For the sake of this task, let us assume the array contains no more than one +' duplicate and missing. +' +' Example 1: +' +' Input: @nums = (1,2,2,4) +' Output: (2,3) +' +' Duplicate is 2 and Missing is 3. +' +' Example 2: +' +' Input: @nums = (1,2,3,4) +' Output: -1 +' +' No duplicate and missing found. +' +' Example 3: +' +' Input: @nums = (1,2,3,3) +' Output: (3,4) +' +' Duplicate is 3 and Missing is 4. + +sub collect_args(nums() as integer) + dim i as integer + i=0 + do while command(i+1)<>"" + redim preserve nums(i) as integer + nums(i)=val(command(i+1)) + i=i+1 + loop +end sub + +function count_nums(nums() as integer, n as integer) as integer + dim i as integer, count as integer + count=0 + for i=0 to ubound(nums) + if nums(i)=n then count=count+1 + next + count_nums=count +end function + +sub print_dups_missing(nums() as integer) + dim i as integer, count as integer, found as boolean + found=false + ' find dups + for i=1 to ubound(nums)+1 + if count_nums(nums(), i)>1 then print i; :found=true + next + ' find missing + for i=1 to ubound(nums)+1 + if count_nums(nums(), i)=0 then print i; :found=true + next + if found then print: else print -1 +end sub + +dim nums() as integer +collect_args nums() +print_dups_missing nums() diff --git a/challenge-208/paulo-custodio/c/ch-1.c b/challenge-208/paulo-custodio/c/ch-1.c new file mode 100644 index 0000000000..25475aeab8 --- /dev/null +++ b/challenge-208/paulo-custodio/c/ch-1.c @@ -0,0 +1,131 @@ +/* +Challenge 208 + +Task 1: Minimum Index Sum +Submitted by: Mohammad S Anwar + +You are given two arrays of strings. + +Write a script to find out all common strings in the given two arrays with +minimum index sum. If no common strings found returns an empty list. +Example 1 + +Input: @list1 = ("Perl", "Raku", "Love") + @list2 = ("Raku", "Perl", "Hate") + +Output: ("Perl", "Raku") + +There are two common strings "Perl" and "Raku". +Index sum of "Perl": 0 + 1 = 1 +Index sum of "Raku": 1 + 0 = 1 + +Example 2 + +Input: @list1 = ("A", "B", "C") + @list2 = ("D", "E", "F") + +Output: () + +No common string found, so no result. + +Example 3 + +Input: @list1 = ("A", "B", "C") + @list2 = ("C", "A", "B") + +Output: ("A") + +There are three common strings "A", "B" and "C". +Index sum of "A": 0 + 1 = 1 +Index sum of "B": 1 + 2 = 3 +Index sum of "C": 2 + 0 = 2 +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void* check_mem(void* p) { + if (!p) { + fputs("Out of memory", stderr); + exit(EXIT_FAILURE); + } + return p; +} + +typedef struct Words { + int count; + char** words; +} Words; + +Words* words_new() { + return check_mem(calloc(1, sizeof(Words))); +} + +void words_clear(Words* words) { + for (int i = 0; i < words->count; i++) + free(words->words[i]); + words->count = 0; +} + +void words_free(Words* words) { + words_clear(words); + free(words); +} + +void words_push(Words* words, const char* word) { + words->count++; + words->words = check_mem(realloc(words->words, + words->count * sizeof(const char*))); + words->words[words->count-1] = check_mem(strdup(word)); +} + +Words* common_strings(Words* list1, Words* list2) { + Words* common = words_new(); + int min_index = list1->count + list2->count + 1; + for (int i = 0; i < list1->count; i++) { + for (int j = 0; j < list2->count; j++) { + if (strcmp(list1->words[i], list2->words[j]) == 0) { + if (i+j < min_index) { + words_clear(common); + words_push(common, list1->words[i]); + min_index = i+j; + } + else if (i+j == min_index) { + words_push(common, list1->words[i]); + min_index = i+j; + } + } + } + } + return common; +} + +int main(int argc, char* argv[]) { + argv++; argc--; + if (argc % 2 != 0 || argc == 0) { + fputs("usage: ch-2 list1 ... list2 ...\n", stderr); + return EXIT_FAILURE; + } + + Words* list1 = words_new(); + Words* list2 = words_new(); + for (int i = 0; i < argc/2; i++) { + words_push(list1, argv[i]); + words_push(list2, argv[i+argc/2]); + } + + Words* common = common_strings(list1, list2); + + if (common->count == 0) + printf("()\n"); + else { + for (int i = 0; i < common->count; i++) + printf("%s ", common->words[i]); + printf("\n"); + } + + words_free(list1); + words_free(list2); + words_free(common); +} diff --git a/challenge-208/paulo-custodio/c/ch-2.c b/challenge-208/paulo-custodio/c/ch-2.c new file mode 100644 index 0000000000..5d1a479d2e --- /dev/null +++ b/challenge-208/paulo-custodio/c/ch-2.c @@ -0,0 +1,93 @@ +/* +Challenge 208 + +Task 2: Duplicate and Missing +Submitted by: Mohammad S Anwar + +You are given an array of integers in sequence with one missing and one duplicate. + +Write a script to find the duplicate and missing integer in the given array. +Return -1 if none found. + +For the sake of this task, let us assume the array contains no more than one +duplicate and missing. + +Example 1: + +Input: @nums = (1,2,2,4) +Output: (2,3) + +Duplicate is 2 and Missing is 3. + +Example 2: + +Input: @nums = (1,2,3,4) +Output: -1 + +No duplicate and missing found. + +Example 3: + +Input: @nums = (1,2,3,3) +Output: (3,4) + +Duplicate is 3 and Missing is 4. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> + +void* check_mem(void* p) { + if (!p) { + fputs("Out of memory", stderr); + exit(EXIT_FAILURE); + } + return p; +} + +int count_nums(int* nums, int nums_size, int n) { + int count = 0; + for (int i = 0; i < nums_size; i++) + if (nums[i] == n) + count++; + return count; +} + +void print_dups_missing(int* nums, int nums_size) { + bool found = false; + // find dups + for (int i = 1; i <= nums_size; i++) { + if (count_nums(nums, nums_size, i) > 1) { + printf("%d ", i); + found = true; + } + } + // find missing + for (int i = 1; i <= nums_size; i++) { + if (count_nums(nums, nums_size, i) == 0) { + printf("%d ", i); + found = true; + } + } + + if (!found) + printf("-1"); + printf("\n"); +} + +int main(int argc, char* argv[]) { + argv++; argc--; + if (argc == 0) { + fputs("usage: ch-2 nums...\n", stderr); + return EXIT_FAILURE; + } + + int* nums = check_mem(malloc(argc * sizeof(int))); + for (int i = 0; i < argc; i++) + nums[i] = atoi(argv[i]); + + print_dups_missing(nums, argc); + + free(nums); +} diff --git a/challenge-208/paulo-custodio/cpp/ch-1.cpp b/challenge-208/paulo-custodio/cpp/ch-1.cpp new file mode 100644 index 0000000000..ba6eaef6fc --- /dev/null +++ b/challenge-208/paulo-custodio/cpp/ch-1.cpp @@ -0,0 +1,95 @@ +/* +Challenge 208 + +Task 1: Minimum Index Sum +Submitted by: Mohammad S Anwar + +You are given two arrays of strings. + +Write a script to find out all common strings in the given two arrays with +minimum index sum. If no common strings found returns an empty list. +Example 1 + +Input: @list1 = ("Perl", "Raku", "Love") + @list2 = ("Raku", "Perl", "Hate") + +Output: ("Perl", "Raku") + +There are two common strings "Perl" and "Raku". +Index sum of "Perl": 0 + 1 = 1 +Index sum of "Raku": 1 + 0 = 1 + +Example 2 + +Input: @list1 = ("A", "B", "C") + @list2 = ("D", "E", "F") + +Output: () + +No common string found, so no result. + +Example 3 + +Input: @list1 = ("A", "B", "C") + @list2 = ("C", "A", "B") + +Output: ("A") + +There are three common strings "A", "B" and "C". +Index sum of "A": 0 + 1 = 1 +Index sum of "B": 1 + 2 = 3 +Index sum of "C": 2 + 0 = 2 +*/ + +#include <iostream> +#include <vector> +#include <string> + +std::vector<std::string> common_strings( + const std::vector<std::string>& list1, + const std::vector<std::string>& list2 +) { + std::vector<std::string> common; + int min_index = list1.size() + list2.size() + 1; + for (size_t i = 0; i < list1.size(); i++) { + for (size_t j = 0; j < list2.size(); j++) { + if (list1[i] == list2[j]) { + if (i+j < min_index) { + common.clear(); + common.push_back(list1[i]); + min_index = i+j; + } + else if (i+j == min_index) { + common.push_back(list1[i]); + min_index = i+j; + } + } + } + } + return common; +} + +int main(int argc, char* argv[]) { + argv++; argc--; + if (argc % 2 != 0 || argc == 0) { + std::cerr << "usage: ch-2 list1 ... list2 ..." << std::endl; + return EXIT_FAILURE; + } + + std::vector<std::string> list1; + std::vector<std::string> list2; + for (int i = 0; i < argc/2; i++) { + list1.push_back(argv[i]); + list2.push_back(argv[i+argc/2]); + } + + std::vector<std::string> common = common_strings(list1, list2); + + if (common.size() == 0) + std::cout << "()" << std::endl; + else { + for (size_t i = 0; i < common.size(); i++) + std::cout << common[i] << " "; + std::cout << std::endl; + } +} diff --git a/challenge-208/paulo-custodio/cpp/ch-2.cpp b/challenge-208/paulo-custodio/cpp/ch-2.cpp new file mode 100644 index 0000000000..b9fedde4e7 --- /dev/null +++ b/challenge-208/paulo-custodio/cpp/ch-2.cpp @@ -0,0 +1,82 @@ +/* +Challenge 208 + +Task 2: Duplicate and Missing +Submitted by: Mohammad S Anwar + +You are given an array of integers in sequence with one missing and one duplicate. + +Write a script to find the duplicate and missing integer in the given array. +Return -1 if none found. + +For the sake of this task, let us assume the array contains no more than one +duplicate and missing. + +Example 1: + +Input: @nums = (1,2,2,4) +Output: (2,3) + +Duplicate is 2 and Missing is 3. + +Example 2: + +Input: @nums = (1,2,3,4) +Output: -1 + +No duplicate and missing found. + +Example 3: + +Input: @nums = (1,2,3,3) +Output: (3,4) + +Duplicate is 3 and Missing is 4. +*/ + +#include <iostream> +#include <vector> + +int count_nums(const std::vector<int>& nums, int n) { + int count = 0; + for (size_t i = 0; i < nums.size(); i++) + if (nums[i] == n) + count++; + return count; +} + +void print_dups_missing(const std::vector<int>& nums) { + bool found = false; + // find dups + for (size_t i = 1; i <= nums.size(); i++) { + if (count_nums(nums, i) > 1) { + std::cout << i << " "; + found = true; + } + } + // find missing + for (size_t i = 1; i <= nums.size(); i++) { + if (count_nums(nums, i) == 0) { + std::cout << i << " "; + found = true; + } + } + + if (!found) + std::cout << -1; + std::cout << std::endl; +} + +int main(int argc, char* argv[]) { + argv++; argc--; + if (argc == 0) { + std::cerr << "usage: ch-2 nums..." << std::endl; + return EXIT_FAILURE; + } + + std::vector<int> nums; + for (int i = 0; i < argc; i++) + nums.push_back(atoi(argv[i])); + + print_dups_missing(nums); +} diff --git a/challenge-208/paulo-custodio/forth/ch-1.fs b/challenge-208/paulo-custodio/forth/ch-1.fs new file mode 100644 index 0000000000..3e800c1cb9 --- /dev/null +++ b/challenge-208/paulo-custodio/forth/ch-1.fs @@ -0,0 +1,131 @@ +#! /usr/bin/env gforth + +\ Challenge 208 +\ +\ Task 1: Minimum Index Sum +\ Submitted by: Mohammad S Anwar +\ +\ You are given two arrays of strings. +\ +\ Write a script to find out all common strings in the given two arrays with +\ minimum index sum. If no common strings found returns an empty list. +\ Example 1 +\ +\ Input: @list1 = ("Perl", "Raku", "Love") +\ @list2 = ("Raku", "Perl", "Hate") +\ +\ Output: ("Perl", "Raku") +\ +\ There are two common strings "Perl" and "Raku". +\ Index sum of "Perl": 0 + 1 = 1 +\ Index sum of "Raku": 1 + 0 = 1 +\ +\ Example 2 +\ +\ Input: @list1 = ("A", "B", "C") +\ @list2 = ("D", "E", "F") +\ +\ Output: () +\ +\ No common string found, so no result. +\ +\ Example 3 +\ +\ Input: @list1 = ("A", "B", "C") +\ @list2 = ("C", "A", "B") +\ +\ Output: ("A") +\ +\ There are three common strings "A", "B" and "C". +\ Index sum of "A": 0 + 1 = 1 +\ Index sum of "B": 1 + 2 = 3 +\ Index sum of "C": 2 + 0 = 2 + +\ string storage: addr, len; strings kept in command line storage +2 CELLS VALUE str.sizeof + +\ string list storage +: list.size ( list -- list-size-addr ) 0 CELLS + ; +: list.item[] ( list idx -- str-addr ) 2* CELLS CELL + + ; + +\ clear list +: list.clear ( list -- ) + 0 SWAP ! +; + +\ push string to list +: list.push { addr len list -- } + addr len list list.size @ list SWAP list.item[] 2! + 1 list list.size +! +; + +\ create list +: list.create ( size -- | name ) + CREATE 0 , ( len ) str.sizeof * ALLOT +; + +\ print list +: list.print ( list -- ) + DUP @ ( len ) + DUP IF + SWAP CELL + SWAP ( addr++ ) + 0 ?DO + DUP 2@ TYPE SPACE + str.sizeof + + LOOP + DROP + ELSE + 2DROP ." ()" + THEN + CR +; + +\ three lists +256 list.create list1 +256 list.create list2 +256 list.create common + +\ collect lists from command line +: collect_args ( -- ) + BEGIN NEXT-ARG DUP WHILE + list1 list.push + REPEAT + 2DROP +; + +\ split list1 to list2 +: split_list { from to -- } + from list.size @ 2 / { n } + n 0 ?DO + from n I + list.item[] 2@ + to list.push + LOOP + n from list.size ! +; + +\ common strings with lowest index +: common_strings { list1 list2 common -- } + list1 list.size @ list2 list.size @ 1+ { min_index } + list1 list.size @ 0 ?DO + list2 list.size @ 0 ?DO + list1 J list.item[] 2@ + list2 I list.item[] 2@ + COMPARE 0= IF + I J + min_index < IF + common list.clear + list1 J list.item[] 2@ common list.push + I J + TO min_index + ELSE I J + min_index = IF + list1 J list.item[] 2@ common list.push + I J + TO min_index + THEN THEN + THEN + LOOP + LOOP +; + +collect_args +list1 list2 split_list +list1 list2 common common_strings +common list.print +BYE diff --git a/challenge-208/paulo-custodio/forth/ch-2.fs b/challenge-208/paulo-custodio/forth/ch-2.fs new file mode 100644 index 0000000000..c163f3c74b --- /dev/null +++ b/challenge-208/paulo-custodio/forth/ch-2.fs @@ -0,0 +1,83 @@ +#! /usr/bin/env gforth + +\ Challenge 208 +\ +\ Task 2: Duplicate and Missing +\ Submitted by: Mohammad S Anwar +\ +\ You are given an array of integers in sequence with one missing and one duplicate. +\ +\ Write a script to find the duplicate and missing integer in the given array. +\ Return -1 if none found. +\ +\ For the sake of this task, let us assume the array contains no more than one +\ duplicate and missing. +\ +\ Example 1: +\ +\ Input: @nums = (1,2,2,4) +\ Output: (2,3) +\ +\ Duplicate is 2 and Missing is 3. +\ +\ Example 2: +\ +\ Input: @nums = (1,2,3,4) +\ Output: -1 +\ +\ No duplicate and missing found. +\ +\ Example 3: +\ +\ Input: @nums = (1,2,3,3) +\ Output: (3,4) +\ +\ Duplicate is 3 and Missing is 4. + +CREATE nums 256 CELLS ALLOT +0 VALUE nums_size + +: nums[] ( i -- addr ) + CELLS nums + +; + +: collect_args ( -- ) + BEGIN NEXT-ARG DUP WHILE + 0 0 2SWAP >NUMBER 2DROP DROP + nums_size nums[] ! + nums_size 1+ TO nums_size + REPEAT + 2DROP +; + +: count_nums { n -- count } + 0 + nums_size 0 ?DO + I nums[] @ n = IF 1+ THEN + LOOP +; + +: print_dups_missing ( -- ) + FALSE { found } + \ find dups + nums_size 1+ 1 ?DO + I count_nums 1 > IF + I . + TRUE TO found + THEN + LOOP + \ find missing + nums_size 1+ 1 ?DO + I count_nums 0= IF + I . + TRUE TO found + THEN + LOOP + \ print missing + found 0= IF -1 . THEN + CR +; + +collect_args +print_dups_missing +BYE diff --git a/challenge-208/paulo-custodio/perl/ch-1.pl b/challenge-208/paulo-custodio/perl/ch-1.pl index c11b91e5f4..3389c64385 100644 --- a/challenge-208/paulo-custodio/perl/ch-1.pl +++ b/challenge-208/paulo-custodio/perl/ch-1.pl @@ -47,7 +47,7 @@ sub common_strings { my($list1, $list2) = @_; my @list1 = @$list1; my @list2 = @$list2; - my $min_index = @list1 + @list2; + my $min_index = @list1 + @list2 + 1; my @common; for my $i (0 .. $#list1) { |
