From 019010d917c7006777dab0bf252b5a2a72c077b4 Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Mon, 20 Mar 2023 15:53:57 +0000 Subject: Add Perl solution --- challenge-198/paulo-custodio/perl/ch-1.pl | 2 - challenge-209/paulo-custodio/Makefile | 2 + challenge-209/paulo-custodio/perl/ch-1.pl | 52 +++++++++++++++++ challenge-209/paulo-custodio/perl/ch-2.pl | 89 ++++++++++++++++++++++++++++++ challenge-209/paulo-custodio/t/test-1.yaml | 10 ++++ challenge-209/paulo-custodio/t/test-2.yaml | 15 +++++ 6 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 challenge-209/paulo-custodio/Makefile create mode 100644 challenge-209/paulo-custodio/perl/ch-1.pl create mode 100644 challenge-209/paulo-custodio/perl/ch-2.pl create mode 100644 challenge-209/paulo-custodio/t/test-1.yaml create mode 100644 challenge-209/paulo-custodio/t/test-2.yaml diff --git a/challenge-198/paulo-custodio/perl/ch-1.pl b/challenge-198/paulo-custodio/perl/ch-1.pl index 058b53b538..4c2ff16f3e 100644 --- a/challenge-198/paulo-custodio/perl/ch-1.pl +++ b/challenge-198/paulo-custodio/perl/ch-1.pl @@ -44,5 +44,3 @@ sub max_gap { @ARGV or die "usage: ch-1.pl nums\n"; my @n=@ARGV; say max_gap(@n); - - 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/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] -> "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. + +use Modern::Perl; + +sub decode { + my($in) = @_; + my $out = ""; + for ($in) { + while ($_ ne '') { + if (s/^0//) { $out .= "a"; } + elsif (s/^10//) { $out .= "b"; } + elsif (s/^11//) { $out .= "c"; } + else { die "invalid coded input: $in\n"; } + } + } + return $out; +} + +@ARGV==1 or die "usage: ch-1.pl bits\n"; +my $in = shift; +my $out = decode($in); +say $out =~ /a$/ ? 1 : 0; diff --git a/challenge-209/paulo-custodio/perl/ch-2.pl b/challenge-209/paulo-custodio/perl/ch-2.pl new file mode 100644 index 0000000000..f034278adf --- /dev/null +++ b/challenge-209/paulo-custodio/perl/ch-2.pl @@ -0,0 +1,89 @@ +#!/usr/bin/perl + +# 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"] ] + +use Modern::Perl; + +sub parse_input { + my(@argv) = @_; + my @accounts; + my $i=0; + while ($i < @argv) { + my $j=$i; + while ($j < @argv && $argv[$j] ne ',') { + $j++; + } + push @accounts, [@argv[$i..$j-1]]; + $i=$j+1; + } + return @accounts; +} + +sub common_email { + my(@accounts)=@_; + my %mails; + for my $i (0..$#accounts) { + for my $j (1..$#{$accounts[$i]}) { + my $mail = $accounts[$i][$j]; + if (exists $mails{$mail}) { + return ($mails{$mail}, $i); + } + else { + $mails{$mail}=$i; + } + } + } + return; +} + +sub merge_accounts { + my(@accounts)=@_; + while (my($a,$b)=common_email(@accounts)) { + # merge a and b + my %mails; + for my $i (1..$#{$accounts[$a]}) { $mails{$accounts[$a][$i]}=1; } + for my $i (1..$#{$accounts[$b]}) { $mails{$accounts[$b][$i]}=1; } + $accounts[$a]=[$accounts[$a][0], sort keys %mails]; + splice(@accounts,$b,1); + } + return @accounts; +} + +sub print_accounts { + my(@accounts) = @_; + for (@accounts) { + say join(" ", @$_); + } +} + +my @accounts=merge_accounts(parse_input(@ARGV)); +print_accounts(@accounts); diff --git a/challenge-209/paulo-custodio/t/test-1.yaml b/challenge-209/paulo-custodio/t/test-1.yaml new file mode 100644 index 0000000000..0cddc5dfde --- /dev/null +++ b/challenge-209/paulo-custodio/t/test-1.yaml @@ -0,0 +1,10 @@ +- setup: + cleanup: + args: 100 + input: + output: 1 +- setup: + cleanup: + args: 1110 + input: + output: 0 diff --git a/challenge-209/paulo-custodio/t/test-2.yaml b/challenge-209/paulo-custodio/t/test-2.yaml new file mode 100644 index 0000000000..fcdf5555f1 --- /dev/null +++ b/challenge-209/paulo-custodio/t/test-2.yaml @@ -0,0 +1,15 @@ +- setup: + cleanup: + args: A a1@a.com a2@a.com , B b1@b.com , A a3@a.com a1@a.com + input: + output: | + |A a1@a.com a2@a.com a3@a.com + |B b1@b.com +- setup: + cleanup: + args: A a1@a.com a2@a.com , B b1@b.com , A a3@a.com , B b2@b.com b1@b.com + input: + output: | + |A a1@a.com a2@a.com + |B b1@b.com b2@b.com + |A a3@a.com -- cgit From 05a0862dc464bcdda8eaca308559334c2a4faebc Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Mon, 20 Mar 2023 18:41:45 +0000 Subject: incomplete --- challenge-209/paulo-custodio/basic/ch-1.bas | 54 +++++++++++++++++ challenge-209/paulo-custodio/basic/ch-2.bas | 90 +++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 challenge-209/paulo-custodio/basic/ch-1.bas create mode 100644 challenge-209/paulo-custodio/basic/ch-2.bas 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..fb9a6300d9 --- /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..b73570d522 --- /dev/null +++ b/challenge-209/paulo-custodio/basic/ch-2.bas @@ -0,0 +1,90 @@ +' 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 a as integer, byref b as integer) as boolean + dim emails_a() as string, emails_b() as string + dim i as integer, j as integer, k as integer + for i=0 to ubound(names) + split(emails(i),,emails_a()) + print names(i);" "; + for j=0 to ubound(emails_a): print emails_a(j);" ";: next + print + next + common_email=false +end function + + +dim i as integer, a as integer, b as integer + +collect_args +if common_email(a, b) then print a, b +for i=0 to ubound(names) + print i;names(i) ',emails(i) +next -- cgit From 24768e7e03a6650db1d81f58ec120b806807fc0f Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Mon, 20 Mar 2023 22:05:03 +0000 Subject: incomplete --- challenge-209/paulo-custodio/basic/ch-2.bas | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/challenge-209/paulo-custodio/basic/ch-2.bas b/challenge-209/paulo-custodio/basic/ch-2.bas index b73570d522..96447e2b53 100644 --- a/challenge-209/paulo-custodio/basic/ch-2.bas +++ b/challenge-209/paulo-custodio/basic/ch-2.bas @@ -68,14 +68,24 @@ sub split(byval text as string, delim as string = " ", ret() as string) loop end sub -function common_email(byref a as integer, byref b as integer) as boolean +function common_email(byref aa as integer, byref bb as integer) as boolean dim emails_a() as string, emails_b() as string - dim i as integer, j as integer, k as integer - for i=0 to ubound(names) - split(emails(i),,emails_a()) - print names(i);" "; - for j=0 to ubound(emails_a): print emails_a(j);" ";: next - print + 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 mails_a(i)=mails_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 -- cgit From da3731bfb028253180da6118717957b1d1226c44 Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Tue, 21 Mar 2023 22:30:27 +0000 Subject: Add Perl solution --- challenge-197/paulo-custodio/Makefile | 2 ++ challenge-197/paulo-custodio/perl/ch-1.pl | 25 ++++++++++++++++ challenge-197/paulo-custodio/perl/ch-2.pl | 46 ++++++++++++++++++++++++++++++ challenge-197/paulo-custodio/t/test-1.yaml | 15 ++++++++++ challenge-197/paulo-custodio/t/test-2.yaml | 20 +++++++++++++ 5 files changed, 108 insertions(+) create mode 100644 challenge-197/paulo-custodio/Makefile create mode 100644 challenge-197/paulo-custodio/perl/ch-1.pl create mode 100644 challenge-197/paulo-custodio/perl/ch-2.pl create mode 100644 challenge-197/paulo-custodio/t/test-1.yaml create mode 100644 challenge-197/paulo-custodio/t/test-2.yaml diff --git a/challenge-197/paulo-custodio/Makefile b/challenge-197/paulo-custodio/Makefile new file mode 100644 index 0000000000..c3c762d746 --- /dev/null +++ b/challenge-197/paulo-custodio/Makefile @@ -0,0 +1,2 @@ +all: + perl ../../challenge-001/paulo-custodio/test.pl diff --git a/challenge-197/paulo-custodio/perl/ch-1.pl b/challenge-197/paulo-custodio/perl/ch-1.pl new file mode 100644 index 0000000000..5c9d599734 --- /dev/null +++ b/challenge-197/paulo-custodio/perl/ch-1.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl + +# Challenge 197 +# +# Task 1: Move Zero +# Submitted by: Mohammad S Anwar +# You are given a list of integers, @list. +# +# Write a script to move all zero, if exists, to the end while maintaining +# the relative order of non-zero elements. +# +# +# Example 1 +# Input: @list = (1, 0, 3, 0, 0, 5) +# Output: (1, 3, 5, 0, 0, 0) +# Example 2 +# Input: @list = (1, 6, 4) +# Output: (1, 6, 4) +# Example 3 +# Input: @list = (0, 1, 0, 2, 0) +# Output: (1, 2, 0, 0, 0) + +use Modern::Perl; + +say join " ", (grep {$_} @ARGV), (grep {!$_} @ARGV); diff --git a/challenge-197/paulo-custodio/perl/ch-2.pl b/challenge-197/paulo-custodio/perl/ch-2.pl new file mode 100644 index 0000000000..85d5da58e0 --- /dev/null +++ b/challenge-197/paulo-custodio/perl/ch-2.pl @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +# Challenge 197 +# +# Task 2: Wiggle Sort +# Submitted by: Mohammad S Anwar +# You are given a list of integers, @list. +# +# Write a script to perform Wiggle Sort on the given list. +# +# +# Wiggle sort would be such as list[0] < list[1] > list[2] < list[3]…. +# +# +# Example 1 +# Input: @list = (1,5,1,1,6,4) +# Output: (1,6,1,5,1,4) +# Example 2 +# Input: @list = (1,3,2,2,3,1) +# Output: (2,3,1,3,1,2) + +use Modern::Perl; + +sub copy_data { + my($to, $to_idx, $from, $from_idx) = @_; + for (; $to_idx >= 0; $to_idx-=2) { + $to->[$to_idx]=$from->[$from_idx++]; + } +} + +sub wiggle_sort { + my(@nums) = @_; + my @copy = sort {$a<=>$b} @nums; + if (scalar(@nums)%2==0) { + copy_data(\@nums, scalar(@nums)-2, \@copy, 0); + copy_data(\@nums, scalar(@nums)-1, \@copy, int(scalar(@nums)/2)); + } + else { + copy_data(\@nums, scalar(@nums)-2, \@copy, 0); + copy_data(\@nums, scalar(@nums)-1, \@copy, int(scalar(@nums)/2)); + } + return @nums; +} + +my @nums = wiggle_sort(@ARGV); +say "@nums"; diff --git a/challenge-197/paulo-custodio/t/test-1.yaml b/challenge-197/paulo-custodio/t/test-1.yaml new file mode 100644 index 0000000000..fd2a3fd918 --- /dev/null +++ b/challenge-197/paulo-custodio/t/test-1.yaml @@ -0,0 +1,15 @@ +- setup: + cleanup: + args: 1 0 3 0 0 5 + input: + output: 1 3 5 0 0 0 +- setup: + cleanup: + args: 1 6 4 + input: + output: 1 6 4 +- setup: + cleanup: + args: 0 1 0 2 0 + input: + output: 1 2 0 0 0 diff --git a/challenge-197/paulo-custodio/t/test-2.yaml b/challenge-197/paulo-custodio/t/test-2.yaml new file mode 100644 index 0000000000..1d7221da1d --- /dev/null +++ b/challenge-197/paulo-custodio/t/test-2.yaml @@ -0,0 +1,20 @@ +- setup: + cleanup: + args: 1 5 1 1 6 4 + input: + output: 1 6 1 5 1 4 +- setup: + cleanup: + args: 1 3 2 2 3 1 + input: + output: 2 3 1 3 1 2 +- setup: + cleanup: + args: 1 3 2 2 3 1 + input: + output: 2 3 1 3 1 2 +- setup: + cleanup: + args: 5 1 6 4 1 + input: + output: 6 1 5 1 4 -- cgit From f036ddd90eca9f7472fed1034d5e223e46a7543f Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Wed, 22 Mar 2023 19:34:38 +0000 Subject: Add C and C++ solutions --- challenge-209/paulo-custodio/basic/ch-1.bas | 34 ++--- challenge-209/paulo-custodio/basic/ch-2.bas | 144 ++++++++++++------- challenge-209/paulo-custodio/c/ch-1.c | 69 +++++++++ challenge-209/paulo-custodio/c/ch-2.c | 216 ++++++++++++++++++++++++++++ challenge-209/paulo-custodio/cpp/ch-1.cpp | 66 +++++++++ challenge-209/paulo-custodio/cpp/ch-2.cpp | 101 +++++++++++++ 6 files changed, 561 insertions(+), 69 deletions(-) create mode 100644 challenge-209/paulo-custodio/c/ch-1.c create mode 100644 challenge-209/paulo-custodio/c/ch-2.c create mode 100644 challenge-209/paulo-custodio/cpp/ch-1.cpp create mode 100644 challenge-209/paulo-custodio/cpp/ch-2.cpp diff --git a/challenge-209/paulo-custodio/basic/ch-1.bas b/challenge-209/paulo-custodio/basic/ch-1.bas index fb9a6300d9..f3b1c1013f 100644 --- a/challenge-209/paulo-custodio/basic/ch-1.bas +++ b/challenge-209/paulo-custodio/basic/ch-1.bas @@ -29,23 +29,23 @@ ' (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 + 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 diff --git a/challenge-209/paulo-custodio/basic/ch-2.bas b/challenge-209/paulo-custodio/basic/ch-2.bas index 96447e2b53..02e2fb621f 100644 --- a/challenge-209/paulo-custodio/basic/ch-2.bas +++ b/challenge-209/paulo-custodio/basic/ch-2.bas @@ -33,68 +33,108 @@ 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 + 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 + 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 mails_a(i)=mails_b(j) then - aa=a: bb=b: common_email=true - exit function - end if - next - end if - next - next - next - common_email=false + 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 -dim i as integer, a as integer, b as integer +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 -if common_email(a, b) then print a, b +merge_accounts for i=0 to ubound(names) - print i;names(i) ',emails(i) + 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 +#include +#include + +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..a5349dac18 --- /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 +#include +#include +#include + +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: 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 +#include + +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..0767787b2d --- /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 +#include +#include +#include + +struct Account { + std::string name; + std::vector 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& 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& 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: name emails... name emails..." << std::endl; + return EXIT_FAILURE; + } + + std::vector 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; + } +} -- cgit From 7edb70c0def87d648efab04eae738f0918503fc1 Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Wed, 22 Mar 2023 22:07:57 +0000 Subject: Add Forth solution --- challenge-209/paulo-custodio/forth/ch-1.fs | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 challenge-209/paulo-custodio/forth/ch-1.fs 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 -- cgit From 19a608784387815b0dac448244689155e0fbd6b1 Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Thu, 23 Mar 2023 19:24:23 +0000 Subject: incomplete --- challenge-209/paulo-custodio/forth/ch-2.fs | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 challenge-209/paulo-custodio/forth/ch-2.fs 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..68740dc2e1 --- /dev/null +++ b/challenge-209/paulo-custodio/forth/ch-2.fs @@ -0,0 +1,32 @@ +#! /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"] ] -- cgit From ac2c8d2a8d71a76611de26bf545df37ceafc09f9 Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Thu, 23 Mar 2023 22:26:15 +0000 Subject: incomplete --- challenge-209/paulo-custodio/forth/ch-2.fs | 88 ++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/challenge-209/paulo-custodio/forth/ch-2.fs b/challenge-209/paulo-custodio/forth/ch-2.fs index 68740dc2e1..769c05f32d 100644 --- a/challenge-209/paulo-custodio/forth/ch-2.fs +++ b/challenge-209/paulo-custodio/forth/ch-2.fs @@ -30,3 +30,91 @@ \ Output: [ ["A", "a1@a.com", "a2@a.com"], \ ["A", "a3@a.com"], \ ["B", "b1@b.com", "b2@b.com"] ] + +\ string list: word with length, dwords with each string pointer and length +: str_list_new ( -- lst ) + CELL ALLOCATE THROW 0 OVER ! +; + +: str_list_delete ( lst -- ) + FREE THROW +; + +: str_list_size ( lst -- size ) + @ +; + +: str_list[] ( lst idx -- addr ) + SWAP CELL + SWAP CELLS 2* + +; + +: str_list_resize ( lst size -- lst ) + 2* CELLS CELL + RESIZE THROW +; + +: str_list_push { addr len lst -- lst } + lst lst str_list_size 1+ str_list_resize TO lst + addr len lst lst str_list_size str_list[] 2! + 1 lst +! + lst +; + +: str_list_type { lst -- } + lst str_list_size 0 ?DO + lst I str_list[] 2@ TYPE SPACE + LOOP +; + +: str_list_sort { lst -- } + lst str_list_size 1 > IF + lst str_list_size 1- 0 ?DO + lst str_list_size I 1+ ?DO + lst J str_list[] 2@ + lst I str_list[] 2@ + 2OVER 2OVER + COMPARE 0> IF + lst J str_list[] 2! + lst I str_list[] 2! + ELSE + 2DROP 2DROP + THEN + LOOP + LOOP + THEN +; + +: str_list_uniq { lst -- } + lst str_list_size 1 > IF + lst str_list_sort + 0 { i } + BEGIN i lst str_list_size 1- < WHILE + lst i str_list[] 2@ + lst i 1+ str_list[] 2@ + COMPARE 0= IF \ remove next entry + lst i 1+ str_list[] + lst i str_list[] + lst str_list_size i - 1- CELLS 2* + MOVE + -1 lst +! + ELSE + i 1+ TO i + THEN + REPEAT + THEN +; + + +str_list_new VALUE lst +lst 64 dump +next-arg lst str_list_push TO lst +next-arg lst str_list_push TO lst +next-arg lst str_list_push TO lst +next-arg lst str_list_push TO lst +next-arg lst str_list_push TO lst +lst 64 dump +lst str_list_type CR +lst str_list_uniq +lst str_list_type CR +lst 64 dump + +~~ bye -- cgit From e6074696335f54b6b80b79e58102fa5dd03faa23 Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Fri, 24 Mar 2023 17:19:06 +0000 Subject: incomplete --- challenge-209/paulo-custodio/forth/ch-2.fs | 170 +++++++++++++++++++++-------- 1 file changed, 126 insertions(+), 44 deletions(-) diff --git a/challenge-209/paulo-custodio/forth/ch-2.fs b/challenge-209/paulo-custodio/forth/ch-2.fs index 769c05f32d..52fb1ce824 100644 --- a/challenge-209/paulo-custodio/forth/ch-2.fs +++ b/challenge-209/paulo-custodio/forth/ch-2.fs @@ -31,50 +31,50 @@ \ ["A", "a3@a.com"], \ ["B", "b1@b.com", "b2@b.com"] ] -\ string list: word with length, dwords with each string pointer and length -: str_list_new ( -- lst ) +\ mails list: word with length, dwords with each string pointer and length +: emails_new ( -- lst ) CELL ALLOCATE THROW 0 OVER ! ; -: str_list_delete ( lst -- ) +: emails_delete ( lst -- ) FREE THROW ; -: str_list_size ( lst -- size ) +: emails_size ( lst -- size ) @ ; -: str_list[] ( lst idx -- addr ) +: emails[] ( lst idx -- addr ) SWAP CELL + SWAP CELLS 2* + ; -: str_list_resize ( lst size -- lst ) +: emails_resize ( lst size -- lst ) 2* CELLS CELL + RESIZE THROW ; -: str_list_push { addr len lst -- lst } - lst lst str_list_size 1+ str_list_resize TO lst - addr len lst lst str_list_size str_list[] 2! +: 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 ; -: str_list_type { lst -- } - lst str_list_size 0 ?DO - lst I str_list[] 2@ TYPE SPACE +: emails_type { lst -- } + lst emails_size 0 ?DO + lst I emails[] 2@ TYPE SPACE LOOP ; -: str_list_sort { lst -- } - lst str_list_size 1 > IF - lst str_list_size 1- 0 ?DO - lst str_list_size I 1+ ?DO - lst J str_list[] 2@ - lst I str_list[] 2@ +: 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 str_list[] 2! - lst I str_list[] 2! + lst J emails[] 2! + lst I emails[] 2! ELSE 2DROP 2DROP THEN @@ -83,17 +83,17 @@ THEN ; -: str_list_uniq { lst -- } - lst str_list_size 1 > IF - lst str_list_sort +: emails_uniq { lst -- } + lst emails_size 1 > IF + lst emails_sort 0 { i } - BEGIN i lst str_list_size 1- < WHILE - lst i str_list[] 2@ - lst i 1+ str_list[] 2@ + 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+ str_list[] - lst i str_list[] - lst str_list_size i - 1- CELLS 2* + lst i 1+ emails[] + lst i emails[] + lst emails_size i - 1- CELLS 2* MOVE -1 lst +! ELSE @@ -103,18 +103,100 @@ THEN ; - -str_list_new VALUE lst -lst 64 dump -next-arg lst str_list_push TO lst -next-arg lst str_list_push TO lst -next-arg lst str_list_push TO lst -next-arg lst str_list_push TO lst -next-arg lst str_list_push TO lst -lst 64 dump -lst str_list_type CR -lst str_list_uniq -lst str_list_type CR -lst 64 dump - -~~ bye +: 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_size accs[] ! + 1 accs +! + accs +; + +: accs_type { accs -- } + accs accs_size 0 ?DO + accs I accs[] @ acc.name 2@ TYPE SPACE + LOOP +; + + +accs_new VALUE accs +S" A" accs accs_push TO accs +accs acc.type +~~ BYE + +next-arg acc acc.emails_push +next-arg acc acc.emails_push +next-arg acc acc.emails_push +next-arg acc acc.emails_push +next-arg acc acc.emails_push + +acc acc.type + +S" B" acc_new VALUE acc2 +S" 123" acc2 acc.emails_push +S" 456" acc2 acc.emails_push +S" 789" acc2 acc.emails_push +acc2 acc.type + +acc acc2 acc_merge +acc acc.type + -- cgit From b06c1ce49bc8269285955b65de8675b52c0abb34 Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Sat, 25 Mar 2023 13:19:42 +0000 Subject: Add Forth solution --- challenge-209/paulo-custodio/forth/ch-2.fs | 259 ++++++++++++++++------------- 1 file changed, 147 insertions(+), 112 deletions(-) diff --git a/challenge-209/paulo-custodio/forth/ch-2.fs b/challenge-209/paulo-custodio/forth/ch-2.fs index 52fb1ce824..b21756d539 100644 --- a/challenge-209/paulo-custodio/forth/ch-2.fs +++ b/challenge-209/paulo-custodio/forth/ch-2.fs @@ -1,115 +1,115 @@ #! /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 ! + CELL ALLOCATE THROW 0 OVER ! ; : emails_delete ( lst -- ) - FREE THROW + FREE THROW ; : emails_size ( lst -- size ) - @ + @ ; : emails[] ( lst idx -- addr ) - SWAP CELL + SWAP CELLS 2* + + SWAP CELL + SWAP CELLS 2* + ; : emails_resize ( lst size -- lst ) - 2* CELLS CELL + RESIZE THROW + 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 + 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 + 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 + 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 + 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 + 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 @@ -118,85 +118,120 @@ : 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 + 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 acc.emails @ emails_delete + acc FREE THROW ; : acc.emails_push { addr len acc -- } - addr len acc acc.emails @ emails_push - acc acc.emails ! + 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_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 ! + 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 ! + CELL ALLOCATE THROW + 0 OVER ! ; : accs_size ( accs -- size ) - @ + @ ; -: accs[] ( accs idx -- addr ) - SWAP CELL + SWAP CELLS + +: accs[] ( accs idx -- addr ) + SWAP CELL + SWAP CELLS + ; : accs_resize ( accs size -- accs ) - 1+ CELLS RESIZE THROW + 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_size accs[] ! - 1 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.name 2@ TYPE SPACE - LOOP -; - - -accs_new VALUE accs -S" A" accs accs_push TO accs -accs acc.type -~~ BYE - -next-arg acc acc.emails_push -next-arg acc acc.emails_push -next-arg acc acc.emails_push -next-arg acc acc.emails_push -next-arg acc acc.emails_push - -acc acc.type - -S" B" acc_new VALUE acc2 -S" 123" acc2 acc.emails_push -S" 456" acc2 acc.emails_push -S" 789" acc2 acc.emails_push -acc2 acc.type - -acc acc2 acc_merge -acc acc.type - + 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 -- cgit From 6737a18810400c88848bb9364f9abf5297a5caef Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Sat, 25 Mar 2023 15:51:06 +0000 Subject: Add Perl, C, C++, BASIC and Forth solutions --- challenge-197/paulo-custodio/basic/ch-1.bas | 64 +++++++++++++++++++++ challenge-197/paulo-custodio/basic/ch-2.bas | 74 +++++++++++++++++++++++++ challenge-197/paulo-custodio/c/ch-1.c | 66 ++++++++++++++++++++++ challenge-197/paulo-custodio/c/ch-2.c | 70 +++++++++++++++++++++++ challenge-197/paulo-custodio/cpp/ch-1.cpp | 53 ++++++++++++++++++ challenge-197/paulo-custodio/cpp/ch-2.cpp | 55 ++++++++++++++++++ challenge-197/paulo-custodio/forth/ch-1.fs | 75 +++++++++++++++++++++++++ challenge-197/paulo-custodio/forth/ch-2.fs | 86 +++++++++++++++++++++++++++++ challenge-197/paulo-custodio/perl/ch-2.pl | 10 +--- challenge-209/paulo-custodio/c/ch-2.c | 2 +- challenge-209/paulo-custodio/cpp/ch-2.cpp | 2 +- 11 files changed, 547 insertions(+), 10 deletions(-) create mode 100644 challenge-197/paulo-custodio/basic/ch-1.bas create mode 100644 challenge-197/paulo-custodio/basic/ch-2.bas create mode 100644 challenge-197/paulo-custodio/c/ch-1.c create mode 100644 challenge-197/paulo-custodio/c/ch-2.c create mode 100644 challenge-197/paulo-custodio/cpp/ch-1.cpp create mode 100644 challenge-197/paulo-custodio/cpp/ch-2.cpp create mode 100644 challenge-197/paulo-custodio/forth/ch-1.fs create mode 100644 challenge-197/paulo-custodio/forth/ch-2.fs diff --git a/challenge-197/paulo-custodio/basic/ch-1.bas b/challenge-197/paulo-custodio/basic/ch-1.bas new file mode 100644 index 0000000000..836b6a7bf3 --- /dev/null +++ b/challenge-197/paulo-custodio/basic/ch-1.bas @@ -0,0 +1,64 @@ +' Challenge 197 +' +' Task 1: Move Zero +' Submitted by: Mohammad S Anwar +' You are given a list of integers, @list. +' +' Write a script to move all zero, if exists, to the end while maintaining +' the relative order of non-zero elements. +' +' +' Example 1 +' Input: @list = (1, 0, 3, 0, 0, 5) +' Output: (1, 3, 5, 0, 0, 0) +' Example 2 +' Input: @list = (1, 6, 4) +' Output: (1, 6, 4) +' Example 3 +' Input: @list = (0, 1, 0, 2, 0) +' Output: (1, 2, 0, 0, 0) + +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 + +sub print_nums(nums() as integer) + dim i as integer + + for i=0 to ubound(nums) + print nums(i); + next + print +end sub + +sub move_zeros(nums() as integer) + dim copy(ubound(nums)) as integer, i as integer, p as integer + + for i=0 to ubound(nums) + copy(i)=nums(i) + next + p=0 + for i=0 to ubound(copy) + if copy(i)<>0 then + nums(p)=copy(i) + p=p+1 + end if + next + for i=0 to ubound(copy) + if copy(i)=0 then + nums(p)=copy(i) + p=p+1 + end if + next +end sub + +dim nums() as integer +collect_args nums() +move_zeros nums() +print_nums nums() diff --git a/challenge-197/paulo-custodio/basic/ch-2.bas b/challenge-197/paulo-custodio/basic/ch-2.bas new file mode 100644 index 0000000000..6979b9b01b --- /dev/null +++ b/challenge-197/paulo-custodio/basic/ch-2.bas @@ -0,0 +1,74 @@ +' Challenge 197 +' +' Task 2: Wiggle Sort +' Submitted by: Mohammad S Anwar +' You are given a list of integers, @list. +' +' Write a script to perform Wiggle Sort on the given list. +' +' +' Wiggle sort would be such as list[0] < list[1] > list[2] < list[3]. +' +' +' Example 1 +' Input: @list = (1,5,1,1,6,4) +' Output: (1,6,1,5,1,4) +' Example 2 +' Input: @list = (1,3,2,2,3,1) +' Output: (2,3,1,3,1,2) + +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 + +sub print_nums(nums() as integer) + dim i as integer + + for i=0 to ubound(nums) + print nums(i); + next + print +end sub + +sub sort(nums() as integer) + dim i as integer, j as integer, n as integer + + for i=lbound(nums) to ubound(nums)-1 + for j=i+1 to ubound(nums) + if nums(i)>nums(j) then + n=nums(i): nums(i)=nums(j): nums(j)=n + end if + next + next +end sub + +sub copy_data(dst() as integer, dst_idx as integer, from() as integer, from_idx as integer) + do while dst_idx>=0 + dst(dst_idx)=from(from_idx) + dst_idx=dst_idx-2 + from_idx=from_idx+1 + loop +end sub + +sub wiggle_sort(nums() as integer) + dim i as integer, j as integer, copy(ubound(nums)) as integer + + for i=0 to ubound(nums) + copy(i)=nums(i) + next + sort copy() + + copy_data nums(), ubound(nums)-1, copy(), 0 + copy_data nums(), ubound(nums), copy(), (ubound(nums)+1)/2 +end sub + +dim nums() as integer +collect_args nums() +wiggle_sort nums() +print_nums nums() diff --git a/challenge-197/paulo-custodio/c/ch-1.c b/challenge-197/paulo-custodio/c/ch-1.c new file mode 100644 index 0000000000..ce6d9efb89 --- /dev/null +++ b/challenge-197/paulo-custodio/c/ch-1.c @@ -0,0 +1,66 @@ +/* +Challenge 197 + +Task 1: Move Zero +Submitted by: Mohammad S Anwar +You are given a list of integers, @list. + +Write a script to move all zero, if exists, to the end while maintaining +the relative order of non-zero elements. + + +Example 1 +Input: @list = (1, 0, 3, 0, 0, 5) +Output: (1, 3, 5, 0, 0, 0) +Example 2 +Input: @list = (1, 6, 4) +Output: (1, 6, 4) +Example 3 +Input: @list = (0, 1, 0, 2, 0) +Output: (1, 2, 0, 0, 0) +*/ + +#include +#include +#include + +void* check_mem(void* p) { + if (!p) { + fputs("Out of memory", stderr); + exit(EXIT_FAILURE); + } + return p; +} + +void move_zeros(int* nums, int nums_size) { + int* copy = check_mem(malloc(nums_size * sizeof(int))); + memcpy(copy, nums, nums_size * sizeof(int)); + int p=0; + for (int i=0; i list[2] < list[3]. + + +Example 1 +Input: @list = (1,5,1,1,6,4) +Output: (1,6,1,5,1,4) +Example 2 +Input: @list = (1,3,2,2,3,1) +Output: (2,3,1,3,1,2) +*/ + +#include +#include +#include + +void* check_mem(void* p) { + if (!p) { + fputs("Out of memory", stderr); + exit(EXIT_FAILURE); + } + return p; +} + +void copy_data(int* to, int to_idx, int* from, int from_idx) { + for (; to_idx>=0; to_idx-=2) + to[to_idx]=from[from_idx++]; +} + +int compare(const void* a, const void* b) { + return *(int*)a - *(int*)b; +} + +void wiggle_sort(int* nums, int nums_size) { + int* copy = check_mem(malloc(nums_size * sizeof(int))); + memcpy(copy, nums, nums_size * sizeof(int)); + qsort(copy, nums_size, sizeof(int), compare); + copy_data(nums, nums_size-2, copy, 0); + copy_data(nums, nums_size-1, copy, nums_size/2); + free(copy); +} + +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