Perl Weekly Challenge 203.
My solutions (task 1 and task 2 ) to the The Weekly Challenge - 203.
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
I use combinations
from Algorithm::Combinatorics
to generate
quadruplets, I grep
the special ones and count them with a oneliner:
perl -MAlgorithm::Combinatorics=combinations -E '
say join " ", @ARGV, "->", 0+grep {$_->[3]==$_->[0]+$_->[1]+$_->[2]} combinations(\@ARGV,4)
' 1 2 3 6
perl -MAlgorithm::Combinatorics=combinations -E '
say join " ", @ARGV, "->", 0+grep {$_->[3]==$_->[0]+$_->[1]+$_->[2]} combinations(\@ARGV,4)
' 1 1 1 3 5
perl -MAlgorithm::Combinatorics=combinations -E '
say join " ", @ARGV, "->", 0+grep {$_->[3]==$_->[0]+$_->[1]+$_->[2]} combinations(\@ARGV,4)
' 3 3 6 4 5
Results:
1 2 3 6 -> 1
1 1 1 3 5 -> 4
3 3 6 4 5 -> 0
The full code is almost identical:
1 # Perl weekly challenge 203
2 # Task 1: Special Quadruplets
3 #
4 # See https://wlmb.github.io/2023/02/06/PWC203/#task-1-special-quadruplets
5 use v5.36;
6 use Algorithm::Combinatorics qw(combinations);
7 say join " ", @ARGV, "->", 0+grep {$_->[3]==$_->[0]+$_->[1]+$_->[2]} combinations(\@ARGV,4);
Examples:
./ch-1.pl 1 2 3 6
./ch-1.pl 1 1 1 3 5
./ch-1.pl 3 3 6 4 5
Results:
1 2 3 6 -> 1
1 1 1 3 5 -> 4
3 3 6 4 5 -> 0
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
I solve this task recursively using the core subroutines opendir
to open source
directories, readdir
to read their contents, -d
to test if a file
is a directory and mkdir
to make new directories. The program fits a
twoliner.
rm -r rem # use a temporal directory for the test
for i in 1 2 3 4 5; do mkdir -p rem/a/b/c/$i; done # prepare the given structure
for i in 1 2 3 5; do touch rem/a/b/c/$i/$i.txt; done
mkdir -p rem/x/y
echo "Before"
tree rem # print the starting directory structure
perl -Mautodie -E '
c(@ARGV); sub c($f, $t){opendir my $h, $f;for(grep {!/^\./ && -d "$f/$_"} readdir($h)){
mkdir "$t/$_"; c("$f/$_", "$t/$_");}}
' rem/a/b/c rem/x/y
echo
echo "After"
tree rem # print resulting structure
Results:
Before
rem
├── a
│ └── b
│ └── c
│ ├── 1
│ │ └── 1.txt
│ ├── 2
│ │ └── 2.txt
│ ├── 3
│ │ └── 3.txt
│ ├── 4
│ └── 5
│ └── 5.txt
└── x
└── y
11 directories, 4 files
After
rem
├── a
│ └── b
│ └── c
│ ├── 1
│ │ └── 1.txt
│ ├── 2
│ │ └── 2.txt
│ ├── 3
│ │ └── 3.txt
│ ├── 4
│ └── 5
│ └── 5.txt
└── x
└── y
├── 1
├── 2
├── 3
├── 4
└── 5
16 directories, 4 files
The full code is similar.
1 # Perl weekly challenge 203
2 # Task 2: Copy Directory
3 #
4 # See https://wlmb.github.io/2023/02/06/PWC203/#task-2-copy-directory
5 use v5.36;
6 die <<~"FIN" if @ARGV!=2;
7 Usage: $0 dir1 dir2
8 to copy the directory structure under dir1 to dir2
9 FIN
10 copydir(@ARGV);
11 sub copydir($from, $to){
12 opendir my $handle, $from || die "Couldn't open $from: $!";
13 for(grep {!/^\./ && -d "$from/$_"} readdir($handle)){
14 mkdir "$to/$_" || die "Couldn't create $to/$_";
15 copydir("$from/$_", "$to/$_");
16 }
17 }
18
Example:
rm -r rem # use a temporal directory for the test
for i in 1 2 3 4 5; do mkdir -p rem/a/b/c/$i; done # prepare the given structure
for i in 1 2 3 5; do touch rem/a/b/c/$i/$i.txt; done
mkdir -p rem/x/y
echo "Before"
tree rem # print the starting directory structure
./ch-2.pl rem/a/b/c rem/x/y
echo
echo "After"
tree rem # print resulting structure
Results:
Before
rem
├── a
│ └── b
│ └── c
│ ├── 1
│ │ └── 1.txt
│ ├── 2
│ │ └── 2.txt
│ ├── 3
│ │ └── 3.txt
│ ├── 4
│ └── 5
│ └── 5.txt
└── x
└── y
11 directories, 4 files
After
rem
├── a
│ └── b
│ └── c
│ ├── 1
│ │ └── 1.txt
│ ├── 2
│ │ └── 2.txt
│ ├── 3
│ │ └── 3.txt
│ ├── 4
│ └── 5
│ └── 5.txt
└── x
└── y
├── 1
├── 2
├── 3
├── 4
└── 5
16 directories, 4 files
Written on February 6, 2023