From 7cadf51023a0bb8e1997038d1442929cb9e08ac0 Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 09:26:32 +0100 Subject: Task 1 done --- challenge-203/luca-ferrari/raku/ch-1.p6 | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 challenge-203/luca-ferrari/raku/ch-1.p6 diff --git a/challenge-203/luca-ferrari/raku/ch-1.p6 b/challenge-203/luca-ferrari/raku/ch-1.p6 new file mode 100644 index 0000000000..9b4475d724 --- /dev/null +++ b/challenge-203/luca-ferrari/raku/ch-1.p6 @@ -0,0 +1,26 @@ +#!raku + +# +# Perl Weekly Challenge 203 +# Task 1 +# +# See +# + +sub MAIN( Bool :$verbose = True, *@list where { @list.grep( * ~~ Int ).elems == @list.elems } ) { + my @quadruplets; + + for 0 ..^ @list.elems -> $a { + for $a ^..^ @list.elems -> $b { + for $b ^..^ @list.elems -> $c { + for $c ^..^ @list.elems -> $d { + my ( $la, $lb, $lc, $ld ) = @list[ $a ], @list[ $b ], @list[ $c ], @list[ $d ]; + @quadruplets.push: [ $la, $lb, $lc, $ld ] if ( ( $la + $lb + $lc ) == $ld ); + } + } + } + } + + @quadruplets.join( "\n -> " ).say if $verbose; + @quadruplets.elems.say; +} -- cgit From 5a361646c02f78a24b57a246154c38e4657f2e60 Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 09:42:21 +0100 Subject: Task2 done --- challenge-203/luca-ferrari/raku/ch-2.p6 | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 challenge-203/luca-ferrari/raku/ch-2.p6 diff --git a/challenge-203/luca-ferrari/raku/ch-2.p6 b/challenge-203/luca-ferrari/raku/ch-2.p6 new file mode 100644 index 0000000000..235d2671d8 --- /dev/null +++ b/challenge-203/luca-ferrari/raku/ch-2.p6 @@ -0,0 +1,19 @@ +#!raku + +# +# Perl Weekly Challenge 203 +# Task 2 +# +# See +# + +sub MAIN( $src, $dst ) { + exit if ! $src.IO.d; + exit if ! $dst.IO.d; + + for $src.IO.dir( test => { ( $src.IO.absolute ~ "/$_" ).IO.d } ) -> $dir { + # skip . and .. directories + next if $dir ~~ / \. ** 1..2 $ /; + $dst.IO.mkdir( $dir.basename ); + } +} -- cgit From e10644c47be99e923d712493e3b75c067ce2d48a Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 09:51:17 +0100 Subject: Task 1 plperl --- challenge-203/luca-ferrari/postgresql/ch-1.plperl | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 challenge-203/luca-ferrari/postgresql/ch-1.plperl diff --git a/challenge-203/luca-ferrari/postgresql/ch-1.plperl b/challenge-203/luca-ferrari/postgresql/ch-1.plperl new file mode 100644 index 0000000000..3e076d0479 --- /dev/null +++ b/challenge-203/luca-ferrari/postgresql/ch-1.plperl @@ -0,0 +1,30 @@ +-- +-- Perl Weekly Challenge 203 +-- Task 1 +-- See +-- + +CREATE SCHEMA IF NOT EXISTS pwc203; + +CREATE OR REPLACE FUNCTION +pwc203.task1_plperl( int[] ) +RETURNS int +AS $CODE$ + my ( $list ) = @_; + my @quadruplets; + + for my $a ( 0 .. scalar( $list->@* ) - 1 ) { + for my $b ( $a + 1 .. scalar( $list->@* ) - 1 ) { + for my $c ( $b + 1 .. scalar( $list->@* ) - 1 ) { + for my $d ( $c + 1 .. scalar( $list->@* ) - 1 ) { + my ( $la, $lb, $lc, $ld ) = ( $list->[ $a ], $list->[ $b ], $list->[ $c ], $list->[ $d ] ); + push @quadruplets, [ $la, $lb, $lc, $ld ] if ( ( $la + $lb + $lc ) == $ld ); + } + } + } + + } + + return scalar @quadruplets; +$CODE$ +LANGUAGE plperl; -- cgit From 12172564b97d462bfcd14fc8dab6063c186bf316 Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 10:06:16 +0100 Subject: Task 2 plperl --- challenge-203/luca-ferrari/postgresql/ch-2.plperl | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 challenge-203/luca-ferrari/postgresql/ch-2.plperl diff --git a/challenge-203/luca-ferrari/postgresql/ch-2.plperl b/challenge-203/luca-ferrari/postgresql/ch-2.plperl new file mode 100644 index 0000000000..bcef6e90be --- /dev/null +++ b/challenge-203/luca-ferrari/postgresql/ch-2.plperl @@ -0,0 +1,34 @@ +-- +-- Perl Weekly Challenge 203 +-- Task 2 +-- See +-- + +CREATE SCHEMA IF NOT EXISTS pwc203; + +CREATE OR REPLACE FUNCTION +pwc203.task2_plperl( text, text ) +RETURNS VOID +AS $CODE$ + use File::Find; + use File::Path qw/make_path/; + + my ( $src, $dst ) = @_; + my @paths; + + my $directory_scanner = sub { + return if ! -d $_; + push @paths, "$dst/$_"; + }; + + + find( { wanted => $directory_scanner } , $src ); + + for ( @paths ) { + make_path( $_ ); + } + + return; + +$CODE$ +LANGUAGE plperlu; -- cgit From 0c5bbe1e2ef583628123c84d5ba07fe83613f4ad Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 10:09:23 +0100 Subject: Task 1 plpgsql --- challenge-203/luca-ferrari/postgresql/ch-1.sql | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 challenge-203/luca-ferrari/postgresql/ch-1.sql diff --git a/challenge-203/luca-ferrari/postgresql/ch-1.sql b/challenge-203/luca-ferrari/postgresql/ch-1.sql new file mode 100644 index 0000000000..16796a6653 --- /dev/null +++ b/challenge-203/luca-ferrari/postgresql/ch-1.sql @@ -0,0 +1,37 @@ +-- +-- Perl Weekly Challenge 203 +-- Task 1 +-- +-- See +-- + +CREATE SCHEMA IF NOT EXISTS pwc203; + +CREATE OR REPLACE FUNCTION +pwc203.task1_plpgsql( l int[] ) +RETURNS int +AS $CODE$ +DECLARE + a int; + b int; + c int; + d int; + total int := 0; +BEGIN + FOR a IN 1 .. array_length( l, 1 ) LOOP + FOR b IN a + 1 .. array_length( l, 1 ) LOOP + FOR c IN b + 1 .. array_length( l, 1 ) LOOP + FOR d IN c + 1 .. array_length( l, 1 ) LOOP + IF l[a] + l[b] + l[c] = l[d] THEN + total := total + 1; + END IF; + END LOOP; + END LOOP; + END LOOP; + END LOOP; + + RETURN total; + +END +$CODE$ +LANGUAGE plpgsql; -- cgit From dc8878779759a9ef0426bf001ea65935ebcbf565 Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 10:11:23 +0100 Subject: Avoid dot folders in plperl implementation --- challenge-203/luca-ferrari/postgresql/ch-2.plperl | 1 + 1 file changed, 1 insertion(+) diff --git a/challenge-203/luca-ferrari/postgresql/ch-2.plperl b/challenge-203/luca-ferrari/postgresql/ch-2.plperl index bcef6e90be..811bb8d843 100644 --- a/challenge-203/luca-ferrari/postgresql/ch-2.plperl +++ b/challenge-203/luca-ferrari/postgresql/ch-2.plperl @@ -18,6 +18,7 @@ AS $CODE$ my $directory_scanner = sub { return if ! -d $_; + return if $_ =~ /^\,{1,2}$/; push @paths, "$dst/$_"; }; -- cgit From f69143dc3ae0fe485285afc22aa3bc93c059a814 Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 10:12:32 +0100 Subject: Task 2 plpgsql --- challenge-203/luca-ferrari/postgresql/ch-2.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 challenge-203/luca-ferrari/postgresql/ch-2.sql diff --git a/challenge-203/luca-ferrari/postgresql/ch-2.sql b/challenge-203/luca-ferrari/postgresql/ch-2.sql new file mode 100644 index 0000000000..1b67d4c3e1 --- /dev/null +++ b/challenge-203/luca-ferrari/postgresql/ch-2.sql @@ -0,0 +1,18 @@ +-- +-- Perl Weekly Challenge 203 +-- Task 2 +-- +-- See +-- + +CREATE SCHEMA IF NOT EXISTS pwc203; + +CREATE OR REPLACE FUNCTION +pwc203.task2_plpgsql( src text, dst text ) +RETURNS VOID +AS $CODE$ +BEGIN + SELECT pwc203.task2_plperl( src, dst ); +END +$CODE$ +LANGUAGE plpgsql; -- cgit From 903685d12ac5baeb8089c664966ae61bc71d2046 Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 10:22:16 +0100 Subject: Fix regular expression to skip dot directories. --- challenge-203/luca-ferrari/raku/ch-2.p6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/challenge-203/luca-ferrari/raku/ch-2.p6 b/challenge-203/luca-ferrari/raku/ch-2.p6 index 235d2671d8..1816488d96 100644 --- a/challenge-203/luca-ferrari/raku/ch-2.p6 +++ b/challenge-203/luca-ferrari/raku/ch-2.p6 @@ -13,7 +13,7 @@ sub MAIN( $src, $dst ) { for $src.IO.dir( test => { ( $src.IO.absolute ~ "/$_" ).IO.d } ) -> $dir { # skip . and .. directories - next if $dir ~~ / \. ** 1..2 $ /; + next if $dir ~~ / ^ \. ** 1..2 $ /; $dst.IO.mkdir( $dir.basename ); } } -- cgit From b3423b79d17fea0a5190f2aeea548496159cfef7 Mon Sep 17 00:00:00 2001 From: Luca Ferrari Date: Mon, 6 Feb 2023 10:30:16 +0100 Subject: Blog references --- challenge-203/luca-ferrari/blog-1.txt | 1 + challenge-203/luca-ferrari/blog-2.txt | 1 + challenge-203/luca-ferrari/blog-3.txt | 1 + challenge-203/luca-ferrari/blog-4.txt | 1 + challenge-203/luca-ferrari/blog-5.txt | 1 + challenge-203/luca-ferrari/blog-6.txt | 1 + 6 files changed, 6 insertions(+) create mode 100644 challenge-203/luca-ferrari/blog-1.txt create mode 100644 challenge-203/luca-ferrari/blog-2.txt create mode 100644 challenge-203/luca-ferrari/blog-3.txt create mode 100644 challenge-203/luca-ferrari/blog-4.txt create mode 100644 challenge-203/luca-ferrari/blog-5.txt create mode 100644 challenge-203/luca-ferrari/blog-6.txt diff --git a/challenge-203/luca-ferrari/blog-1.txt b/challenge-203/luca-ferrari/blog-1.txt new file mode 100644 index 0000000000..fe3704370a --- /dev/null +++ b/challenge-203/luca-ferrari/blog-1.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2023/02/06/PerlWeeklyChallenge203.html#task1 diff --git a/challenge-203/luca-ferrari/blog-2.txt b/challenge-203/luca-ferrari/blog-2.txt new file mode 100644 index 0000000000..1818e95ffa --- /dev/null +++ b/challenge-203/luca-ferrari/blog-2.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2023/02/06/PerlWeeklyChallenge203.html#task2 diff --git a/challenge-203/luca-ferrari/blog-3.txt b/challenge-203/luca-ferrari/blog-3.txt new file mode 100644 index 0000000000..20d1b4f647 --- /dev/null +++ b/challenge-203/luca-ferrari/blog-3.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2023/02/06/PerlWeeklyChallenge203.html#task1plperl diff --git a/challenge-203/luca-ferrari/blog-4.txt b/challenge-203/luca-ferrari/blog-4.txt new file mode 100644 index 0000000000..0fe4b24847 --- /dev/null +++ b/challenge-203/luca-ferrari/blog-4.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2023/02/06/PerlWeeklyChallenge203.html#task2plperl diff --git a/challenge-203/luca-ferrari/blog-5.txt b/challenge-203/luca-ferrari/blog-5.txt new file mode 100644 index 0000000000..e3572b45de --- /dev/null +++ b/challenge-203/luca-ferrari/blog-5.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2023/02/06/PerlWeeklyChallenge203.html#task1plpgsql diff --git a/challenge-203/luca-ferrari/blog-6.txt b/challenge-203/luca-ferrari/blog-6.txt new file mode 100644 index 0000000000..f38b17941b --- /dev/null +++ b/challenge-203/luca-ferrari/blog-6.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2023/02/06/PerlWeeklyChallenge203.html#task2plpgsql -- cgit From 999265fd360b23c90f2071c5be32ad1e7e2db834 Mon Sep 17 00:00:00 2001 From: dcw Date: Mon, 6 Feb 2023 09:50:40 +0000 Subject: (belatedly did and) committed my solutions to this challenge, both tasks, in C and Perl as usual --- challenge-202/duncan-c-white/C/Makefile | 19 +++ challenge-202/duncan-c-white/C/README | 9 ++ challenge-202/duncan-c-white/C/args.c | 207 ++++++++++++++++++++++++++++ challenge-202/duncan-c-white/C/args.h | 11 ++ challenge-202/duncan-c-white/C/ch-1.c | 84 +++++++++++ challenge-202/duncan-c-white/C/ch-2.c | 90 ++++++++++++ challenge-202/duncan-c-white/C/parseints.c | 114 +++++++++++++++ challenge-202/duncan-c-white/C/parseints.h | 1 + challenge-202/duncan-c-white/C/printarray.c | 39 ++++++ challenge-202/duncan-c-white/C/printarray.h | 1 + challenge-202/duncan-c-white/README | 78 +++++++---- challenge-202/duncan-c-white/perl/ch-1.pl | 93 +++++++++++++ challenge-202/duncan-c-white/perl/ch-2.pl | 103 ++++++++++++++ 13 files changed, 820 insertions(+), 29 deletions(-) create mode 100644 challenge-202/duncan-c-white/C/Makefile create mode 100644 challenge-202/duncan-c-white/C/README create mode 100644 challenge-202/duncan-c-white/C/args.c create mode 100644 challenge-202/duncan-c-white/C/args.h create mode 100644 challenge-202/duncan-c-white/C/ch-1.c create mode 100644 challenge-202/duncan-c-white/C/ch-2.c create mode 100644 challenge-202/duncan-c-white/C/parseints.c create mode 100644 challenge-202/duncan-c-white/C/parseints.h create mode 100644 challenge-202/duncan-c-white/C/printarray.c create mode 100644 challenge-202/duncan-c-white/C/printarray.h create mode 100755 challenge-202/duncan-c-white/perl/ch-1.pl create mode 100755 challenge-202/duncan-c-white/perl/ch-2.pl diff --git a/challenge-202/duncan-c-white/C/Makefile b/challenge-202/duncan-c-white/C/Makefile new file mode 100644 index 0000000000..bf2d32d1a1 --- /dev/null +++ b/challenge-202/duncan-c-white/C/Makefile @@ -0,0 +1,19 @@ +# Makefile rules generated by CB +CC = gcc +CFLAGS = -Wall -g +LDFLAGS = -lm +BUILD = ch-1 ch-2 + +all: $(BUILD) + +clean: + /bin/rm -f $(BUILD) *.o core a.out + +args.o: args.c +ch-1: ch-1.o args.o parseints.o printarray.o +ch-1.o: ch-1.c args.h parseints.h printarray.h +ch-2: ch-2.o args.o parseints.o printarray.o +ch-2.o: ch-2.c args.h parseints.h printarray.h +parseints.o: parseints.c args.h parseints.h printarray.h +printarray.o: printarray.c + diff --git a/challenge-202/duncan-c-white/C/README b/challenge-202/duncan-c-white/C/README new file mode 100644 index 0000000000..e0fb8e8359 --- /dev/null +++ b/challenge-202/duncan-c-white/C/README @@ -0,0 +1,9 @@ +Thought I'd also have a go at translating ch-1.pl and ch-2.pl into C.. + +Both C versions produce near-identical (non-debugging and even debugging) +output to the Perl originals. + +They use most of my regular support modules: +- a command-line argument processing module args.[ch], +- a csvlist-of-int parsing module parseints.[ch], and +- an int-array printing module printarray.[ch]. diff --git a/challenge-202/duncan-c-white/C/args.c b/challenge-202/duncan-c-white/C/args.c new file mode 100644 index 0000000000..d4a2d38b9a --- /dev/null +++ b/challenge-202/duncan-c-white/C/args.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include +#include +#include + + +bool debug = false; + + +// process_flag_noarg( name, argc, argv ); +// Process the -d flag, and check that there are no +// remaining arguments. +void process_flag_noarg( char *name, int argc, char **argv ) +{ + int arg=1; + if( argc>1 && strcmp( argv[arg], "-d" ) == 0 ) + { + debug = true; + arg++; + } + + int left = argc-arg; + if( left != 0 ) + { + fprintf( stderr, "Usage: %s [-d]\n", name ); + exit(1); + } +} + + +// int argno = process_flag_n_args( name, argc, argv, n, argmsg ); +// Process the -d flag, and check that there are exactly +// n remaining arguments, return the index position of the first +// argument. If not, generate a fatal Usage error using the argmsg. +// +int process_flag_n_args( char *name, int argc, char **argv, int n, char *argmsg ) +{ + int arg=1; + if( argc>1 && strcmp( argv[arg], "-d" ) == 0 ) + { + debug = true; + arg++; + } + + int left = argc-arg; + if( left != n ) + { + fprintf( stderr, "Usage: %s [-d] %s\n Exactly %d " + "arguments needed\n", name, argmsg, n ); + exit(1); + } + return arg; +} + + +// int argno = process_flag_n_m_args( name, argc, argv, min, max, argmsg ); +// Process the -d flag, and check that there are between +// min and max remaining arguments, return the index position of the first +// argument. If not, generate a fatal Usage error using the argmsg. +// +int process_flag_n_m_args( char *name, int argc, char **argv, int min, int max, char *argmsg ) +{ + int arg=1; + if( argc>1 && strcmp( argv[arg], "-d" ) == 0 ) + { + debug = true; + arg++; + } + + int left = argc-arg; + if( left < min || left > max ) + { + fprintf( stderr, "Usage: %s [-d] %s\n Between %d and %d " + "arguments needed\n", name, argmsg, min, max ); + exit(1); + } + return arg; +} + + +// process_onenumarg_default( name, argc, argv, defvalue, &n ); +// Process the -d flag, and check that there is a single +// remaining numeric argument (or no arguments, in which case +// we use the defvalue), putting it into n +void process_onenumarg_default( char *name, int argc, char **argv, int defvalue, int *n ) +{ + char argmsg[100]; + sprintf( argmsg, "[int default %d]", defvalue ); + int arg = process_flag_n_m_args( name, argc, argv, 0, 1, argmsg ); + + *n = arg == argc ? defvalue : atoi( argv[arg] ); +} + + +// process_onenumarg( name, argc, argv, &n ); +// Process the -d flag, and check that there is a single +// remaining numeric argument, putting it into n +void process_onenumarg( char *name, int argc, char **argv, int *n ) +{ + int arg = process_flag_n_args( name, argc, argv, 1, "int" ); + + // argument is in argv[arg] + *n = atoi( argv[arg] ); +} + + +// process_twonumargs( name, argc, argv, &m, &n ); +// Process the -d flag, and check that there are 2 +// remaining numeric arguments, putting them into m and n +void process_twonumargs( char *name, int argc, char **argv, int *m, int *n ) +{ + int arg = process_flag_n_args( name, argc, argv, 2, "int" ); + + // arguments are in argv[arg] and argv[arg+1] + *m = atoi( argv[arg++] ); + *n = atoi( argv[arg] ); +} + + +// process_twostrargs() IS DEPRECATED: use process_flag_n_m_args() instead + + +// int arr[100]; +// int nel = process_listnumargs( name, argc, argv, arr, 100 ); +// Process the -d flag, and check that there are >= 2 +// remaining numeric arguments, putting them into arr[0..nel-1] +// and returning nel. +int process_listnumargs( char *name, int argc, char **argv, int *arr, int maxel ) +{ + int arg=1; + if( argc>1 && strcmp( argv[arg], "-d" ) == 0 ) + { + debug = true; + arg++; + } + + int left = argc-arg; + if( left < 2 ) + { + fprintf( stderr, "Usage: %s [-d] list_of_numeric_args\n", name ); + exit(1); + } + if( left > maxel ) + { + fprintf( stderr, "%s: more than %d args\n", name, maxel ); + exit(1); + } + + // elements are in argv[arg], argv[arg+1]... + + if( debug ) + { + printf( "debug: remaining arguments are in arg=%d, " + "firstn=%s, secondn=%s..\n", + arg, argv[arg], argv[arg+1] ); + } + + int nel = 0; + for( int i=arg; i +#include +#include +#include +#include +#include + +#include "args.h" +#include "parseints.h" +#include "printarray.h" + + +// bool isodd = isodd( x ); +// Return 1 iff x is odd; else 0. +// +bool isodd( int x ) +{ + return x % 2 == 1; +} + + +// +// bool hasodds = has3odds( list, nel ); +// Return true iff list has 3 consecutive odd numbers; else false. +// +bool has3odds( int *list, int nel ) +{ + for( int i=0; i 2 elements\n" ); + exit(1); + } + + if( debug ) + { + printf( "debug: initial list: " ); + print_int_array( 60, nel, list, ',', stdout ); + putchar( '\n' ); + } + + bool hasodds = has3odds( list, nel ); + printf( "%d\n", (int)hasodds ); + + free( list ); + + return 0; +} diff --git a/challenge-202/duncan-c-white/C/ch-2.c b/challenge-202/duncan-c-white/C/ch-2.c new file mode 100644 index 0000000000..af2845861e --- /dev/null +++ b/challenge-202/duncan-c-white/C/ch-2.c @@ -0,0 +1,90 @@ +// +// Task 2: Widest Valley +// +// C version. +// + +#include +#include +#include +#include +#include +#include + +#include "args.h" +#include "parseints.h" +#include "printarray.h" + + +// int len = find_valley( spos, list, nel ); +// find the leftmost longest sequence of one or more adjacent numbers +// where initially the numbers go down (or stay the same) and then they +// go up (or stay the same). +// +int find_valley( int spos, int *list, int nel ) +{ + int curr = list[spos]; + int p = spos+1; + for( ; p= curr; curr=list[p++] ) + { + } + if( debug ) + { + printf( "debug: found valley from pos %d to pos %d\n", + spos, p-1 ); + } + return p-spos; +} + + +int main( int argc, char **argv ) +{ + int argno = process_flag_n_m_args( "widest-valley", argc, argv, + 1, 1000, "intlist" ); + int nel; + int *list = parse_int_args( argc, argv, argno, &nel ); + + if( nel == 0 ) + { + fprintf( stderr, "widest-valley: need a list of > 0 elements\n" ); + exit(1); + } + + if( debug ) + { + printf( "debug: initial list: " ); + print_int_array( 60, nel, list, ',', stdout ); + putchar( '\n' ); + } + + int maxw = 0; + int maxw_spos = 0; + + for( int spos=0; spos maxw ) + { + if( debug ) + { + printf( "debug: found new widest valley " + "starting at %d: width %d\n", spos, w ); + } + maxw = w; + maxw_spos = spos; + } + } + + for( int i=0; i0 ) printf( ", " ); + printf( "%d", list[maxw_spos+i] ); + } + putchar( '\n' ); + + free( list ); + return 0; +} diff --git a/challenge-202/duncan-c-white/C/parseints.c b/challenge-202/duncan-c-white/C/parseints.c new file mode 100644 index 0000000000..0fb9985633 --- /dev/null +++ b/challenge-202/duncan-c-white/C/parseints.c @@ -0,0 +1,114 @@ +// Simple routine to parse one or more arguments, +// looking for individual +ints or comma-separated +// lists of +ints. +// + +#include +#include +#include +#include +#include +#include + +#include "args.h" +#include "printarray.h" +#include "parseints.h" + +typedef struct +{ + int nel; // current number of elements + int maxel; // maximum number of elements allocated + int *list; // malloc()d list of integers +} intlist; + + +// +// intlist il.. then initialize il.. then: +// add_one( element, &il ); +// +static void add_one( int x, intlist *p ) +{ + if( p->nel > p->maxel ) + { + p->maxel += 128; + p->list = realloc( p->list, p->maxel ); + assert( p->list ); + } + #if 0 + if( debug ) + { + printf( "PIA: appending %d to result at " + "pos %d\n", x, p->nel ); + } + #endif + p->list[p->nel++] = x; +} + + +// +// intlist il.. then initialize il.. then: +// add_one_arg( argstr, &il ); +// +static void add_one_arg( char *argstr, intlist *p ) +{ + int x; + if( !check_unsigned_int(argstr,&x) ) + { + fprintf( stderr, "PIA: arg %s must be +int\n", argstr ); + exit(1); + } + add_one( x, p ); +} + + +// +// int nel; +// int *ilist = parse_int_args( argc, argv, argno, &nel ); +// process all arguments argv[argno..argc-1], extracting either +// single ints or comma-separated lists of ints from those arguments, +// accumulate all integers in a dynarray list, storing the total number +// of elements in nel. This list must be freed by the caller. +// Note that the list of elements used to be terminated by a -1 value, +// but I've commented this out from now on. +// +int *parse_int_args( int argc, char **argv, int argno, int *nel ) +{ + int *result = malloc( 128 * sizeof(int) ); + assert( result ); + intlist il = { 0, 128, result }; + + #if 0 + if( debug ) + { + printf( "PIA: parsing ints from args %d..%d\n", argno, argc-1 ); + } + #endif + for( int i=argno; i +#include + + +// print_int_array( maxw, nelements, results[], sep, outfile ); +// format results[0..nelements-1] as a separated +// list onto outfile with lines <= maxw chars long. +// produces a whole number of lines of output - without the trailing '\n' +void print_int_array( int maxw, int nel, int *results, char sep, FILE *out ) +{ + int linelen = 0; + for( int i=0; i maxw ) + { + fputc( '\n', out ); + linelen = 0; + } else if( i>0 ) + { + fputc( ' ', out ); + linelen++; + } + + linelen += len; + fprintf( out, "%s", buf ); + if( i0 ) + //{ + // fputc( '\n', out ); + //} +} diff --git a/challenge-202/duncan-c-white/C/printarray.h b/challenge-202/duncan-c-white/C/printarray.h new file mode 100644 index 0000000000..40efb83277 --- /dev/null +++ b/challenge-202/duncan-c-white/C/printarray.h @@ -0,0 +1 @@ +extern void print_int_array( int maxw, int nel, int * results, char sep, FILE * out ); diff --git a/challenge-202/duncan-c-white/README b/challenge-202/duncan-c-white/README index 28f5718a9a..c6dd8b8b1c 100644 --- a/challenge-202/duncan-c-white/README +++ b/challenge-202/duncan-c-white/README @@ -1,52 +1,72 @@ -Task 1: Missing Numbers +Task 1: Consecutive Odds -You are given an array of unique numbers. Write a script to find out -all missing numbers in the range 0..$n where $n is the array size. +You are given an array of integers. -Example 1 +Write a script to print 1 if there are THREE consecutive odds in the +given array otherwise print 0. - Input: @array = (0,1,3) - Output: 2 +Example 1 - The array size i.e. total element count is 3, so the range is 0..3. - The missing number is 2 in the given array. +Input: @array = (1,5,3,6) +Output: 1 Example 2 - Input: @array = (0,1) - Output: 2 +Input: @array = (2,6,3,5) +Output: 0 + +Example 3 + +Input: @array = (1,2,3,4) +Output: 0 - The array size is 2, therefore the range is 0..2. - The missing number is 2. +Example 4 -MY NOTES: pretty easy. +Input: @array = (2,3,5,7) +Output: 1 + +MY NOTES: very easy. GUEST LANGUAGE: As a bonus, I also had a go at translating ch-1.pl into C (look in the C directory for the translation) -Task 2: Penny Piles +Task 2: Widest Valley + +Given a profile as a list of altitudes, return the leftmost widest +valley. A valley is defined as a subarray of the profile consisting +of two parts: the first part is non-increasing and the second part is +non-decreasing. Either part can be empty. + +Example 1 + +Input: 1, 5, 5, 2, 8 +Output: 5, 5, 2, 8 + +Example 2 + +Input: 2, 6, 8, 5 +Output: 2, 6, 8 + +Example 3 -You are given an integer, $n > 0. +Input: 9, 8, 13, 13, 2, 2, 15, 17 +Output: 13, 13, 2, 2, 15, 17 -Write a script to determine the number of ways of putting $n pennies in a row of piles of ascending heights from left to right. -Example +Example 4 -Input: $n = 5 -Output: 7 +Input: 2, 1, 2, 1, 3 +Output: 2, 1, 2 -Since $n=5, there are 7 ways of stacking 5 pennies in ascending piles: +Example 5 - 1 1 1 1 1 - 1 1 1 2 - 1 2 2 - 1 1 3 - 2 3 - 1 4 - 5 +Input: 1, 3, 3, 2, 1, 2, 3, 3, 2 +Output: 3, 3, 2, 1, 2, 3, 3 -MY NOTES: not quite so easy, but doable. Sounds recursive to me. -Let's produce the array of answers too.. +MY NOTES: also quite easy, once we remove the negative "non-increasing" +language and realise we mean "find the leftmost longest sequence of one +or more adjacent numbers where initially the numbers go down (or stay +the same) and then they go up (or stay the same)." GUEST LANGUAGE: As a bonus, I also had a go at translating ch-2.pl into C (look in the C directory for the translation) diff --git a/challenge-202/duncan-c-white/perl/ch-1.pl b/challenge-202/duncan-c-white/perl/ch-1.pl new file mode 100755 index 0000000000..3536e2a0b7 --- /dev/null +++ b/challenge-202/duncan-c-white/perl/ch-1.pl @@ -0,0 +1,93 @@ +#!/usr/bin/perl +# +# Task 1: Consecutive Odds +# +# You are given an array of integers. +# +# Write a script to print 1 if there are THREE consecutive odds in the +# given array otherwise print 0. +# +# Example 1 +# +# Input: @array = (1,5,3,6) +# Output: 1 +# +# Example 2 +# +# Input: @array = (2,6,3,5) +# Output: 0 +# +# Example 3 +# +# Input: @array = (1,2,3,4) +# Output: 0 +# +# Example 4 +# +# Input: @array = (2,3,5,7) +# Output: 1 +# +# MY NOTES: very easy. +# +# GUEST LANGUAGE: As a bonus, I also had a go at translating ch-1.pl +# into C (look in the C directory for the translation) +# + +use strict; +use warnings; +use feature 'say'; +use Getopt::Long; +use Data::Dumper; + +my $debug=0; +die "Usage: 3-consec-odds [--debug] intlist\n" + unless GetOptions( "debug"=>\$debug ) && @ARGV>0; + +my @list = split( /,/, join(',',@ARGV) ); + +die "3-consec-odds: need at least 3 ints in list\n" unless @list>2; + +=pod + +=head2 my $isodd = isodd( $x ); + +Return 1 iff $x is odd; else 0. + +=cut +sub isodd +{ + my( $x ) = @_; + return $x % 2 == 1 ? 1 : 0; +} + + +=pod + +=head2 my $has3odds = has3odds( @list ); + +Return 1 iff @list has 3 consecutive odd numbers; else 0. + +=cut +sub has3odds +{ + my( @list ) = @_; + my $n = @list; + + for( my $spos=0; $spos<$n-2; $spos++ ) + { + next unless isodd( $list[$spos] ); + say "debug: found odd element $list[$spos] at pos $spos" + if $debug; + if( isodd( $list[$spos+1] ) && isodd( $list[$spos+2] ) ) + { + say "debug: found 3 consec odd elements $list[$spos], ". + "$list[$spos+1], $list[$spos+2] starting at ". + "pos $spos" if $debug; + return 1; + } + } + return 0; +} + +my $has3odds = has3odds( @list ); +say $has3odds; diff --git a/challenge-202/duncan-c-white/perl/ch-2.pl b/challenge-202/duncan-c-white/perl/ch-2.pl new file mode 100755 index 0000000000..4da1d39a78 --- /dev/null +++ b/challenge-202/duncan-c-white/perl/ch-2.pl @@ -0,0 +1,103 @@ +#!/usr/bin/perl +# +# Task 2: Widest Valley +# +# Given a profile as a list of altitudes, return the leftmost widest +# valley. A valley is defined as a subarray of the profile consisting +# of two parts: the first part is non-increasing and the second part is +# non-decreasing. Either part can be empty. +# +# Example 1 +# +# Input: 1, 5, 5, 2, 8 +# Output: 5, 5, 2, 8 +# +# Example 2 +# +# Input: 2, 6, 8, 5 +# Output: 2, 6, 8 +# +# Example 3 +# +# Input: 9, 8, 13, 13, 2, 2, 15, 17 +# Output: 13, 13, 2, 2, 15, 17 +# +# Example 4 +# +# Input: 2, 1, 2, 1, 3 +# Output: 2, 1, 2 +# +# Example 5 +# +# Input: 1, 3, 3, 2, 1, 2, 3, 3, 2 +# Output: 3, 3, 2, 1, 2, 3, 3 +# +# MY NOTES: also quite easy, once we remove the negative "non-increasing" +# language and realise we mean "find the leftmost longest sequence of one +# or more adjacent numbers where initially the numbers go down (or stay +# the same) and then they go up (or stay the same)." +# +# GUEST LANGUAGE: As a bonus, I also had a go at translating ch-2.pl +# into C (look in the C directory for the translation) +# + +use strict; +use warnings; +use feature 'say'; +use Getopt::Long; +use Function::Parameters; +use Data::Dumper; + +my $debug=0; +die "Usage: widest-valley [--debug] intlist\n" + unless GetOptions( "debug"=>\$debug ) && @ARGV > 0; + +my @list = split( /,/, join(',',@ARGV) ); + +my $n = @list; + +die "widest-valley: need at least 1 int in list\n" unless $n>0; + + +=pod + +=head2 my $len = find_valley( $spos, @list ); + +find the leftmost longest sequence of one or more adjacent numbers +where initially the numbers go down (or stay the same) and then they +go up (or stay the same). + +=cut +fun find_valley( $spos, @list ) +{ + my $n = @list; + my $curr = $list[$spos]; + my $p = $spos+1; + for( ; $p<$n && $list[$p] <= $curr; $curr=$list[$p++] ) + { + } + for( ; $p<$n && $list[$p] >= $curr; $curr=$list[$p++] ) + { + } + my $p1 = $p-1; + say "debug: found valley from pos $spos to pos $p1" if $debug; + return $p-$spos; +} + + +my $maxw = 0; +my $maxw_spos = 0; + +for( my $spos=0; $spos<$n; $spos++ ) +{ + my $w = find_valley( $spos, @list ); + if( $w > $maxw ) + { + say "debug: found new widest valley starting at $spos: width $w" if $debug; + $maxw = $w; + $maxw_spos = $spos; + } +} + + +say join( ', ', @list[$maxw_spos..$maxw_spos+$maxw-1] ); -- cgit From a423131c4c7d2efce817cb7d0936ec8ea9cff1d0 Mon Sep 17 00:00:00 2001 From: Peter Campbell Smith Date: Mon, 6 Feb 2023 14:16:22 +0000 Subject: Week 203 submission --- challenge-203/peter-campbell-smith/blog.txt | 1 + challenge-203/peter-campbell-smith/perl/ch-1.pl | 91 +++++++++++++++++++++++++ challenge-203/peter-campbell-smith/perl/ch-2.pl | 44 ++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 challenge-203/peter-campbell-smith/blog.txt create mode 100755 challenge-203/peter-campbell-smith/perl/ch-1.pl create mode 100755 challenge-203/peter-campbell-smith/perl/ch-2.pl diff --git a/challenge-203/peter-campbell-smith/blog.txt b/challenge-203/peter-campbell-smith/blog.txt new file mode 100644 index 0000000000..a1d240181a --- /dev/null +++ b/challenge-203/peter-campbell-smith/blog.txt @@ -0,0 +1 @@ +https://pjcs-pwc.blogspot.com/2023/02/quads-and-directory-enquiries.html diff --git a/challenge-203/peter-campbell-smith/perl/ch-1.pl b/challenge-203/peter-campbell-smith/perl/ch-1.pl new file mode 100755 index 0000000000..7a56ca9725 --- /dev/null +++ b/challenge-203/peter-campbell-smith/perl/ch-1.pl @@ -0,0 +1,91 @@ +#!/usr/bin/perl + +# Peter Campbell Smith - 2023-02-06 + +use v5.28; +use utf8; +use warnings; +use Time::HiRes qw(time); + +# Task: You are given an array of integers. Write a script to find out the total special quadruplets for the +# given array. Special Quadruplets are such that satisfies the following 2 rules: +# 1) nums[a] + nums[b] + nums[c] == nums[d] +# 2) a < b < c < d + +# Blog: https://pjcs-pwc.blogspot.com/2023/02/quads-and-directory-enquiries.html + +my (@tests, $test, @nums, $a, $b, $c, $d, $last, $rubric, $count, @big, $secs, $max); + +@tests = ([1, 2, 3, 6], [1, 1, 1, 3, 5], [3, 3, 6, 4, 5], [3, -2, -5, -4]); + +# create a longer test +for $a (0 .. 150) { + $big[$a] = int(rand(50_000)); +} +push @tests, \@big; + +# loop over tests +say qq[----- simple version -----\n]; +for $test (@tests) { + + # initialise + @nums = @$test; + say qq[Input: \@nums = (] . join(', ', @nums) . ')'; + + $last = scalar(@nums) - 1; + $rubric = ''; + $count = 0; + $secs = time; + + # nested loops over a, b, c and d + for $a (0 .. $last - 3) { + for $b ($a + 1 .. $last - 2) { + for $c ($b + 1 .. $last - 1) { + for $d ($c + 1 .. $last) { + if ($nums[$a] + $nums[$b] + $nums[$c] == $nums[$d]) { + $count ++; + $rubric .= qq[\$nums[$a] + \$nums[$b] + \$nums[$c] == \$nums[$d] | $nums[$a] + $nums[$b] + $nums[$c] == $nums[$d]\n]; + } + } + } + } + } + say qq[Output: $count (] . sprintf('time: %0.2f', time - $secs) . qq[ secs)\n\n$rubric]; +} + +# faster version - abandon each loop if the partial sum exceeds the maximum number in @nums +say qq[----- improved version -----/n]; +for $test (@tests) { + + # initialise + @nums = @$test; + say qq[Input: \@nums = (] . join(', ', @nums) . ')'; + + $last = scalar(@nums) - 1; + $rubric = ''; + $count = 0; + $secs = time; + + # find the largest number + $max = -1e10; + for $a (@nums) { + $max = $a if $a > $max; + } + + # nested loops over a, b, c and d, but abandon the b and c loops if the partial sum exceeds $max + for $a (0 .. $last - 3) { + for $b ($a + 1 .. $last - 2) { + next if $nums[$a] + $nums[$b] > $max; + for $c ($b + 1 .. $last - 1) { + next if $nums[$a] + $nums[$b] + $nums[$c] > $max; + for $d ($c + 1 .. $last) { + if ($nums[$a] + $nums[$b] + $nums[$c] == $nums[$d]) { + $count ++; + $rubric .= qq[\$nums[$a] + \$nums[$b] + \$nums[$c] == \$nums[$d] | $nums[$a] + $nums[$b] + $nums[$c] == $nums[$d]\n]; + } + } + } + } + } + say qq[Output: $count (] . sprintf('time: %0.2f', time - $secs) . qq[ secs)\n\n$rubric]; +} diff --git a/challenge-203/peter-campbell-smith/perl/ch-2.pl b/challenge-203/peter-campbell-smith/perl/ch-2.pl new file mode 100755 index 0000000000..5d1326254b --- /dev/null +++ b/challenge-203/peter-campbell-smith/perl/ch-2.pl @@ -0,0 +1,44 @@ +#!/usr/bin/perl + +# Peter Campbell Smith - 2023-02-06 + +use v5.28; +use utf8; +use warnings; +use Time::HiRes qw(time); + +# Task: You are given path to two folders, $source and $target. Write a script that recursively copy the directories +# in $source to $target, without copying any contained files. + +# Blog: https://pjcs-pwc.blogspot.com/2023/02/quads-and-directory-enquiries.html + +my ($base, $source, $target); + +$base = '/home/pi/PWC'; +$source = "$base/a/b/c"; +$target = "$base/x/y"; + +copy_dirs($source, $target); + +sub copy_dirs { + + my ($source, $target, @files, $f); + ($source, $target) = @_; + + # read the contents of $source + chdir $source; + opendir(DIR, '.') or die qq[cannot open $source $!]; + @files = readdir DIR; + closedir DIR; + + # if there are dirs other than . and .. created them in target + for $f (@files) { + next if $f =~ m|^\.\.?$|; # ignore . and .. + next unless -d qq[$source/$f]; + mkdir qq[$target/$f] or die qq[cannot make dir $target/$f $!]; + say qq[created dir $target/$f]; + + # recurse to create any subfolders + copy_dirs (qq[$source/$f], qq[$target/$f]); + } +} \ No newline at end of file -- cgit From 8c26ca049fb8a84e40861ec1436844928893d174 Mon Sep 17 00:00:00 2001 From: Luis Mochan Date: Mon, 6 Feb 2023 11:47:39 -0600 Subject: Solve PWC203 --- challenge-203/wlmb/blog.txt | 2 ++ challenge-203/wlmb/perl/ch-1.pl | 8 ++++++++ challenge-203/wlmb/perl/ch-2.pl | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 challenge-203/wlmb/blog.txt create mode 100755 challenge-203/wlmb/perl/ch-1.pl create mode 100755 challenge-203/wlmb/perl/ch-2.pl diff --git a/challenge-203/wlmb/blog.txt b/challenge-203/wlmb/blog.txt new file mode 100644 index 0000000000..a0136b9825 --- /dev/null +++ b/challenge-203/wlmb/blog.txt @@ -0,0 +1,2 @@ +https://wlmb.github.io/2023/02/06/PWC203/ + diff --git a/challenge-203/wlmb/perl/ch-1.pl b/challenge-203/wlmb/perl/ch-1.pl new file mode 100755 index 0000000000..2ffe8784d4 --- /dev/null +++ b/challenge-203/wlmb/perl/ch-1.pl @@ -0,0 +1,8 @@ +#!/usr/bin/env perl +# Perl weekly challenge 203 +# Task 1: Special Quadruplets +# +# See https://wlmb.github.io/2023/02/06/PWC203/#task-1-special-quadruplets +use v5.36; +use Algorithm::Combinatorics qw(combinations); +say join " ", @ARGV, "->", 0+grep {$_->[3]==$_->[0]+$_->[1]+$_->[2]} combinations(\@ARGV,4); diff --git a/challenge-203/wlmb/perl/ch-2.pl b/challenge-203/wlmb/perl/ch-2.pl new file mode 100755 index 0000000000..c134316a03 --- /dev/null +++ b/challenge-203/wlmb/perl/ch-2.pl @@ -0,0 +1,18 @@ +#!/usr/bin/env perl +# Perl weekly challenge 203 +# Task 2: Copy Directory +# +# See https://wlmb.github.io/2023/02/06/PWC203/#task-2-copy-directory +use v5.36; +die <<~"FIN" if @ARGV!=2; + Usage: $0 dir1 dir2 + to copy the directory structure under dir1 to dir2 + FIN +copydir(@ARGV); +sub copydir($from, $to){ + opendir my $handle, $from || die "Couldn't open $from: $!"; + for(grep {!/^\./ && -d "$from/$_"} readdir($handle)){ + mkdir "$to/$_" || die "Couldn't create $to/$_"; + copydir("$from/$_", "$to/$_"); + } +} -- cgit From 23f81855bbce069d0b09a383c8d731f80ccb6495 Mon Sep 17 00:00:00 2001 From: Mark <53903062+andemark@users.noreply.github.com> Date: Mon, 6 Feb 2023 22:39:21 +0000 Subject: Challenge 203 Solutions (Raku) --- challenge-203/mark-anderson/raku/ch-1.raku | 14 ++++++++++++++ challenge-203/mark-anderson/raku/ch-2.raku | 6 ++++++ 2 files changed, 20 insertions(+) create mode 100644 challenge-203/mark-anderson/raku/ch-1.raku create mode 100644 challenge-203/mark-anderson/raku/ch-2.raku diff --git a/challenge-203/mark-anderson/raku/ch-1.raku b/challenge-203/mark-anderson/raku/ch-1.raku new file mode 100644 index 0000000000..31893a645d --- /dev/null +++ b/challenge-203/mark-anderson/raku/ch-1.raku @@ -0,0 +1,14 @@ +#!/usr/bin/env raku +use Test; + +is special-quadruplets(1, 2, 3, 6), 1; +is special-quadruplets(1, 1, 1, 3, 5), 4; +is special-quadruplets(3, 3, 6, 4, 5), 0; + +sub special-quadruplets(*@a) +{ + .elems given gather for @a.combinations(4) + { + .take if ([+] .[^3]) == .[3] + } +} diff --git a/challenge-203/mark-anderson/raku/ch-2.raku b/challenge-203/mark-anderson/raku/ch-2.raku new file mode 100644 index 0000000000..9384852bd5 --- /dev/null +++ b/challenge-203/mark-anderson/raku/ch-2.raku @@ -0,0 +1,6 @@ +#!/usr/bin/env raku + +my $source = '/usr/home/andemark/tmp/a/b/c'.IO; +my $destination = '/usr/home/andemark/tmp/x/y'.IO; + +mkdir $destination.add: .basename for $source.dir; -- cgit From a752151b6ed34638684245b115caadb1e6618f98 Mon Sep 17 00:00:00 2001 From: Dave Jacoby Date: Mon, 6 Feb 2023 20:21:43 -0500 Subject: #203 DAJ --- challenge-203/dave-jacoby/perl/ch-1.pl | 62 ++++++++++++++++++++++++++++++++++ challenge-203/dave-jacoby/perl/ch-2.pl | 37 ++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 challenge-203/dave-jacoby/perl/ch-1.pl create mode 100644 challenge-203/dave-jacoby/perl/ch-2.pl diff --git a/challenge-203/dave-jacoby/perl/ch-1.pl b/challenge-203/dave-jacoby/perl/ch-1.pl new file mode 100644 index 0000000000..923904e9e5 --- /dev/null +++ b/challenge-203/dave-jacoby/perl/ch-1.pl @@ -0,0 +1,62 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use experimental qw{ say postderef signatures state }; + +use List::Util qw{ sum0 }; +use Getopt::Long; + +my $verbose = 0; + +GetOptions( + 'verbose' => \$verbose, +); + + +my @examples = ( + + [ 1, 2, 3, 6 ], + [ 1, 1, 1, 3, 5 ], + [ 3, 3, 6, 4, 5 ] +); + +for my $e (@examples) { + my $list = join ',', $e->@*; + my $out = special_quadrant($e); + say <<"END"; + Input: \@array = ($list) + Output: $out +END +} + +sub special_quadrant ( $arrayref, $pos = 0, $resultref = [] ) { + my $output; + + # case: resultref is the right size + if ( scalar $resultref->@* == 4 ) { + my @results = $resultref->@*; + my $sum = sum0 @results[ 0, 1, 2 ]; + if ( $sum == $results[3] ) { + say join ' ', @results if $verbose; + return 1; + } + return 0; + } + + # case: we've run out of data + return 0 if !defined $arrayref->[$pos]; + + my $newref = []; + $newref->@* = $resultref->@*; + $output += + special_quadrant( $arrayref, $pos + 1, $newref ); # don't include this + push $newref->@*, $arrayref->[$pos]; + $output += + special_quadrant( $arrayref, $pos + 1, $newref ); # include this + return $output; +} + +sub is_odd ( $n ) { + return $n % 2 ? 1 : 0; +} diff --git a/challenge-203/dave-jacoby/perl/ch-2.pl b/challenge-203/dave-jacoby/perl/ch-2.pl new file mode 100644 index 0000000000..05f3bdb4bc --- /dev/null +++ b/challenge-203/dave-jacoby/perl/ch-2.pl @@ -0,0 +1,37 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use experimental qw{ say postderef signatures state }; + +use Getopt::Long; + +my $source = './a/b/c'; +my $target = './x/y'; +my $verbose = 0; + +GetOptions( + 'source=s' => \$source, + 'target=s' => \$target, + 'verbose' => \$verbose, +); + +copy_directory( $source, $target ); + +sub copy_directory ( $source, $target ) { + return unless -d $source; + return unless -d $target; + my @dirs; + if ( opendir my $dh, $source ) { + for my $f ( sort readdir $dh ) { + my $s = join '/', $source, $f; + my $t = join '/', $target, $f; + next if $f =~ /^\./; + next unless -d $s; + next if -d $t; + mkdir $t; + copy_directory( $s, $t ); + say join ' => ', $s, $t if $verbose; + } + } +} -- cgit From 93b128e4276795b7579e936b006b640a9e1b3653 Mon Sep 17 00:00:00 2001 From: David Ferrone Date: Mon, 6 Feb 2023 22:38:08 -0500 Subject: Week 203 --- challenge-203/zapwai/perl/ch-1.pl | 23 +++++++++++++++++++++++ challenge-203/zapwai/perl/ch-2.pl | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 challenge-203/zapwai/perl/ch-1.pl create mode 100644 challenge-203/zapwai/perl/ch-2.pl diff --git a/challenge-203/zapwai/perl/ch-1.pl b/challenge-203/zapwai/perl/ch-1.pl new file mode 100644 index 0000000000..fe6eefcd89 --- /dev/null +++ b/challenge-203/zapwai/perl/ch-1.pl @@ -0,0 +1,23 @@ +use v5.30.0; +my @array = (1,2,3,6); +#my @array = (1,1,1,3,5); +#my @array = (3,3,6,4,5); +my $str; +my $cnt; +for my $a (0 .. $#array - 3) { + for my $b ($a + 1 .. $#array - 2) { + for my $c ($b + 1 .. $#array - 1) { + for my $d ($c + 1 .. $#array) { + my $sum = $array[$a] + $array[$b] + $array[$c]; + if ($sum == $array[$d]) { + $cnt++ ; + $str .= "\$array[$a] + \$array[$b] + \$array[$c] == \$array[$d]\n"; + } + } + } + } +} +say "Input: \@array = (".join(",",@array).")"; +$cnt = 0 unless ($cnt); +say "Output: $cnt"; +print $str; diff --git a/challenge-203/zapwai/perl/ch-2.pl b/challenge-203/zapwai/perl/ch-2.pl new file mode 100644 index 0000000000..f762a169fe --- /dev/null +++ b/challenge-203/zapwai/perl/ch-2.pl @@ -0,0 +1,33 @@ +use v5.30.0; +my $source = '/a/b/c/'; +my $target = '/x/y/'; + +opendir my $dh, $source or die "$!"; +my @files = readdir $dh; +closedir $dh; +my @dirs; +foreach (@files) { + next if (($_ eq ".") or ($_ eq "..")); + push @dirs, $_ if (-d $source.$_); +} +for (@dirs) { + #mkdir $target.$_; + say $target.$_; + proc($_); +} + +sub proc { + my $wd = shift; + opendir my $dh, $source.$wd or die "$!"; + my @files = readdir $dh; + closedir $dh; + foreach (@files) { + my $dir = "$wd/$_"; + next if (($_ eq ".") or ($_ eq "..")); + if (-d $source.$dir) { + push @dirs, $dir; +# mkdir $target.$dir; + say $target.$dir; + } + } +} -- cgit From 0aac952c473c73d45fa8d694c6e61243b06bf65f Mon Sep 17 00:00:00 2001 From: Thomas Köhler Date: Tue, 7 Feb 2023 06:48:05 +0100 Subject: Add solution 203 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Köhler --- challenge-203/jeanluc2020/blog-1.txt | 1 + challenge-203/jeanluc2020/blog-2.txt | 1 + challenge-203/jeanluc2020/perl/ch-1.pl | 73 ++++++++++++++++++++++++++++ challenge-203/jeanluc2020/perl/ch-2.pl | 89 ++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 challenge-203/jeanluc2020/blog-1.txt create mode 100644 challenge-203/jeanluc2020/blog-2.txt create mode 100755 challenge-203/jeanluc2020/perl/ch-1.pl create mode 100755 challenge-203/jeanluc2020/perl/ch-2.pl diff --git a/challenge-203/jeanluc2020/blog-1.txt b/challenge-203/jeanluc2020/blog-1.txt new file mode 100644 index 0000000000..8a869fdcca --- /dev/null +++ b/challenge-203/jeanluc2020/blog-1.txt @@ -0,0 +1 @@ +http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-203-1.html diff --git a/challenge-203/jeanluc2020/blog-2.txt b/challenge-203/jeanluc2020/blog-2.txt new file mode 100644 index 0000000000..65ee4cd21d --- /dev/null +++ b/challenge-203/jeanluc2020/blog-2.txt @@ -0,0 +1 @@ +http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-203-2.html diff --git a/challenge-203/jeanluc2020/perl/ch-1.pl b/challenge-203/jeanluc2020/perl/ch-1.pl new file mode 100755 index 0000000000..6a9c63fb60 --- /dev/null +++ b/challenge-203/jeanluc2020/perl/ch-1.pl @@ -0,0 +1,73 @@ +#!/usr/bin/perl +# https://theweeklychallenge.org/blog/perl-weekly-challenge-203/#TASK1 +# +# Task 1: Special Quadruplets +# +# You are given an array of integers. +# +# Write a script to find out the total special quadruplets for the given array. +# +## Special Quadruplets are such that satisfies the following 2 rules. +## 1) nums[a] + nums[b] + nums[c] == nums[d] +## 2) a < b < c < d +# +# +## Example 1 +## +## Input: @nums = (1,2,3,6) +## Output: 1 +## +## Since the only special quadruplets found is $nums[0] + $nums[1] + $nums[2] == $nums[3]. +# +## Example 2 +## +## Input: @nums = (1,1,1,3,5) +## Output: 4 +## +## $nums[0] + $nums[1] + $nums[2] == $nums[3] +## $nums[0] + $nums[1] + $nums[3] == $nums[4] +## $nums[0] + $nums[2] + $nums[3] == $nums[4] +## $nums[1] + $nums[2] + $nums[3] == $nums[4] +# +## Example 3 +## +## Input: @nums = (3,3,6,4,5) +## Output: 0 +# +############################################################ +## +## discussion +## +############################################################ +# +# this is pretty straight forward, just walk the array with 4 variables +# and in each step check the condition + +use strict; +use warnings; +use feature 'say'; + +my @examples = ( + [1,2,3,6], + [1,1,1,3,5], + [3,3,6,4,5] +); + +foreach my $nums (@examples) { + say "Found " . get_quadruples(@$nums) . " for (" . join(", ", @$nums) . ")"; +} + +sub get_quadruples { + my @nums = @_; + my $count = 0; + foreach my $A (0..$#nums) { + foreach my $B ($A+1..$#nums) { + foreach my $C ($B+1..$#nums) { + foreach my $D ($C+1..$#nums) { + $count++ if $nums[$A]+$nums[$B]+$nums[$C] == $nums[$D]; + } + } + } + } + return $count; +} diff --git a/challenge-203/jeanluc2020/perl/ch-2.pl b/challenge-203/jeanluc2020/perl/ch-2.pl new file mode 100755 index 0000000000..9809b80bb3 --- /dev/null +++ b/challenge-203/jeanluc2020/perl/ch-2.pl @@ -0,0 +1,89 @@ +#!/usr/bin/perl +# https://theweeklychallenge.org/blog/perl-weekly-challenge-203/#TASK2 +# Task 2: Copy Directory +# +# You are given path to two folders, $source and $target. +# +# Write a script that recursively copy the directory from $source to $target except any files. +# +## Example +## +## Input: $source = '/a/b/c' and $target = '/x/y' +## +## Source directory structure: +## +## ├── a +## │ └── b +## │ └── c +## │ ├── 1 +## │ │ └── 1.txt +## │ ├── 2 +## │ │ └── 2.txt +## │ ├── 3 +## │ │ └── 3.txt +## │ ├── 4 +## │ └── 5 +## │ └── 5.txt +## +## Target directory structure: +## +## ├── x +## │ └── y +## +## Expected Result: +## +## ├── x +## │ └── y +## | ├── 1 +## │ ├── 2 +## │ ├── 3 +## │ ├── 4 +## │ └── 5 +# +############################################################ +## +## discussion +## +############################################################ +# +# This basically has to duplicate a directory tree, but without +# any files - which I would interpret as "not even special files +# like named pipes, device files, symlinks etc" (the whole code +# would be much more complicated to handle those, albeit not +# impossible to do) +# While the example above uses absolute source and target directories, +# there is no reason why this couldn't also work with relative +# source and target as well. +# We can either do this whole thing manually or use File::Find. +# Since the latter is much more convenient, we try it here ;-) + +use strict; +use warnings; +use File::Find; + +my ($source, $target) = @ARGV; +die "Usage: $0 " unless $source and $target; + +find( { "wanted" => \&wanted, "no_chdir" => 1 } , $source); + +sub wanted { + my $new = $File::Find::name; + if(-d $new) { + $new =~ s/^\Q$source\E/$target/; + ensure_dir($new); + } +} + +# create a directory and all its parents if missing +sub ensure_dir { + my $dir = shift; + $dir =~ s/\/*$//; # remove trailing "/" + return if -d $dir; + if($dir =~ m/\//) { + # we seem to have multiple parts in this path + my $prefix = $dir; + $prefix =~ s#/[^/]*$##; + ensure_dir($prefix); # make sure all parents exist + } + mkdir $dir or die "Can't mkdir $dir: $!"; +} -- cgit From b27a88ca431bba4fe5036ab54348367b45bc9cd3 Mon Sep 17 00:00:00 2001 From: Mariano Spadaccini Date: Tue, 7 Feb 2023 17:02:50 +0100 Subject: PWC 203 - Perl, Python, Go, Bash, Korn shell --- challenge-202/spadacciniweb/perl/ch-2.pl | 4 +- challenge-203/spadacciniweb/bash/ch-2.bash | 12 ++++ challenge-203/spadacciniweb/go/ch-1.go | 73 +++++++++++++++++++++ challenge-203/spadacciniweb/go/ch-2.go | 101 +++++++++++++++++++++++++++++ challenge-203/spadacciniweb/ksh/ch-2.ksh | 14 ++++ challenge-203/spadacciniweb/perl/ch-1.pl | 55 ++++++++++++++++ challenge-203/spadacciniweb/perl/ch-2.pl | 84 ++++++++++++++++++++++++ challenge-203/spadacciniweb/python/ch-1.py | 51 +++++++++++++++ challenge-203/spadacciniweb/python/ch-2.py | 63 ++++++++++++++++++ 9 files changed, 455 insertions(+), 2 deletions(-) create mode 100644 challenge-203/spadacciniweb/bash/ch-2.bash create mode 100644 challenge-203/spadacciniweb/go/ch-1.go create mode 100644 challenge-203/spadacciniweb/go/ch-2.go create mode 100644 challenge-203/spadacciniweb/ksh/ch-2.ksh create mode 100644 challenge-203/spadacciniweb/perl/ch-1.pl create mode 100644 challenge-203/spadacciniweb/perl/ch-2.pl create mode 100644 challenge-203/spadacciniweb/python/ch-1.py create mode 100644 challenge-203/spadacciniweb/python/ch-2.py diff --git a/challenge-202/spadacciniweb/perl/ch-2.pl b/challenge-202/spadacciniweb/perl/ch-2.pl index 5676cf92bf..eb9ebe294f 100644 --- a/challenge-202/spadacciniweb/perl/ch-2.pl +++ b/challenge-202/spadacciniweb/perl/ch-2.pl @@ -33,8 +33,8 @@ my @input = @ARGV; die "Input error\n" if scalar @input < 1 or - scalar map { $_ =~ /^\d+$/ ? () : 1 } - @input != 0; + (scalar map { $_ =~ /^\d+$/ ? () : 1 } + @input) != 0; my @valley; foreach my $min (0..$#input) { diff --git a/challenge-203/spadacciniweb/bash/ch-2.bash b/challenge-203/spadacciniweb/bash/ch-2.bash new file mode 100644 index 0000000000..022c932d20 --- /dev/null +++ b/challenge-203/spadacciniweb/bash/ch-2.bash @@ -0,0 +1,12 @@ +#!/bin/bash + +echo -n "path source: " +read SOURCE + +[ -d "$SOURCE" ] || { echo "$SOURCE directory does not exist."; exit 1; } + +echo -n "path target: " +read TARGET +[ -d "$TARGET" ] || { echo "$TARGET directory does not exist."; exit 1; } + +rsync -av -f"+ */" -f"- *" $SOURCE/ $TARGET diff --git a/challenge-203/spadacciniweb/go/ch-1.go b/challenge-203/spadacciniweb/go/ch-1.go new file mode 100644 index 0000000000..945656d43d --- /dev/null +++ b/challenge-203/spadacciniweb/go/ch-1.go @@ -0,0 +1,73 @@ +/* +Task 1: Special Quadruplets +Submitted by: Mohammad S Anwar + +You are given an array of integers. +Write a script to find out the total special quadruplets for the given array. + +Special Quadruplets are such that satisfies the following 2 rules. +1) nums[a] + nums[b] + nums[c] == nums[d] +2) a < b < c < d + + +Example 1 +Input: @nums = (1,2,3,6) +Output: 1 +Since the only special quadruplets found is $nums[0] + $nums[1] + $nums[2] == $nums[3]. + +Example 2 +Input: @nums = (1,1,1,3,5) +Output: 4 +$nums[0] + $nums[1] + $nums[2] == $nums[3] +$nums[0] + $nums[1] + $nums[3] == $nums[4] +$nums[0] + $nums[2] + $nums[3] == $nums[4] +$nums[1] + $nums[2] + $nums[3] == $nums[4] + +Example 3 +Input: @nums = (3,3,6,4,5) +Output: 0 +*/ + +package main + +import ( + "fmt" + "log" + "os" + "strconv" +) + +type quad struct { + i, j, k, z int +} + +func main() { + arrStr := os.Args[1:] + if (len(arrStr) < 4) { + log.Fatal("input error") + } + + arrInt := make([]int, 0) + for i := 0; i <= len(arrStr)-1; i++ { + value, err := strconv.Atoi(arrStr[i]) + if (err != nil) { + log.Fatal(err) + } + arrInt = append(arrInt, value) + } + + quadruplets := make([]quad, 0) + for i := 0; i <= len(arrInt)-4; i++ { + for j := i+1; j <= len(arrInt)-3; j++ { + for k := j+1; k <= len(arrInt)-2; k++ { + for z := k+1; z <= len(arrInt)-1; z++ { + if arrInt[i] + arrInt[j] + arrInt[k] == arrInt[z] { + quadruplets = append(quadruplets, quad{i, j, k, z}) + } + } + } + } + } + + fmt.Println(len(quadruplets)) +} diff --git a/challenge-203/spadacciniweb/go/ch-2.go b/challenge-203/spadacciniweb/go/ch-2.go new file mode 100644 index 0000000000..98f4873535 --- /dev/null +++ b/challenge-203/spadacciniweb/go/ch-2.go @@ -0,0 +1,101 @@ +/* +Task 2: Copy Directory +Submitted by: Julien Fiegehenn + +You are given path to two folders, $source and $target. +Write a script that recursively copy the directory from $source to $target except any files. + +Example +Input: $source = '/a/b/c' and $target = '/x/y' + +Source directory structure: + +├── a +│ └── b +│ └── c +│ ├── 1 +│ │ └── 1.txt +│ ├── 2 +│ │ └── 2.txt +│ ├── 3 +│ │ └── 3.txt +│ ├── 4 +│ └── 5 +│ └── 5.txt + +Target directory structure: + +├── x +│ └── y + +Expected Result: + +├── x +│ └── y +| ├── 1 +│ ├── 2 +│ ├── 3 +│ ├── 4 +│ └── 5 +*/ + +package main + +import ( + "fmt" + "log" + "path/filepath" + "os" + "strings" +) + +func main() { + var dirs []string + var source string + var target string + + fmt.Print("path source: ") + fmt.Scanf("%s", &source) + + fileInfo, err := os.Stat(source) + if err != nil { + log.Fatal(err) + } else if !fileInfo.IsDir() { + log.Fatalf("%s directory does not exist.", source) + } + + fmt.Print("path target: ") + fmt.Scanf("%s", &target) + + fileInfo, err = os.Stat(target) + if err != nil { + log.Fatal(err) + } else if !fileInfo.IsDir() { + log.Fatalf("%s directory does not exist.", target) + } + + err = filepath.Walk(source, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + if len(path) > len(source) { + dirFmt := path[len(source)+1:] + dirs = append(dirs, dirFmt) + } + } + return err + }) + + if err != nil { + log.Println(err) + } + + for _, currDir := range dirs { + outDir := strings.Join( []string{target, currDir}, "/") + err := os.Mkdir(outDir, 0750) + if err != nil && !os.IsExist(err) { + log.Fatal(err) + } + } +} diff --git a/challenge-203/spadacciniweb/ksh/ch-2.ksh b/challenge-203/spadacciniweb/ksh/ch-2.ksh new file mode 100644 index 0000000000..768123ecac --- /dev/null +++ b/challenge-203/spadacciniweb/ksh/ch-2.ksh @@ -0,0 +1,14 @@ +#!/usr/bin/ksh + +echo -n "path source: " +read SOURCE + +[ -d "$SOURCE" ] || { echo "$SOURCE directory does not exist."; exit 1; } + +echo -n "path target: " +read TARGET +[ -d "$TARGET" ] || { echo "$TARGET directory does not exist."; exit 1; } + +cd $SOURCE +find . -type d -exec mkdir -p "$TARGET/{}" \; +cd - diff --git a/challenge-203/spadacciniweb/perl/ch-1.pl b/challenge-203/spadacciniweb/perl/ch-1.pl new file mode 100644 index 0000000000..72413345de --- /dev/null +++ b/challenge-203/spadacciniweb/perl/ch-1.pl @@ -0,0 +1,55 @@ +#!/usr/bin/env perl + +# Task 1: Special Quadruplets +# Submitted by: Mohammad S Anwar +# +# You are given an array of integers. +# Write a script to find out the total special quadruplets for the given array. +# +# Special Quadruplets are such that satisfies the following 2 rules. +# 1) nums[a] + nums[b] + nums[c] == nums[d] +# 2) a < b < c < d +# +# +# Example 1 +# Input: @nums = (1,2,3,6) +# Output: 1 +# +# Since the only special quadruplets found is $nums[0] + $nums[1] + $nums[2] == $nums[3]. +# +# Example 2 +# Input: @nums = (1,1,1,3,5) +# Output: 4 +# +# $nums[0] + $nums[1] + $nums[2] == $nums[3] +# $nums[0] + $nums[1] + $nums[3] == $nums[4] +# $nums[0] + $nums[2] + $nums[3] == $nums[4] +# $nums[1] + $nums[2] + $nums[3] == $nums[4] +# +# Example 3 +# Input: @nums = (3,3,6,4,5) +# Output: 0 + +use strict; +use warnings; + +my @input = @ARGV; +die "Input error\n" + if scalar @input < 4 + or + (scalar map { $_ =~ /^\d+$/ ? () : 1 } + @input) != 0; + +my @quadruplets = (); +foreach my $i (0..$#input-3) { + foreach my $j ($i+1..$#input-2) { + foreach my $k ($j+1..$#input-1) { + foreach my $z ($k+1..$#input) { + push @quadruplets, [$i, $j, $k, $z] + if $input[$i] + $input[$j] + $input[$k] == $input[$z]; + } + } + }