Skip to content

Commit

Permalink
- Added Perl and Swift solutions for Challenge #71.
Browse files Browse the repository at this point in the history
  • Loading branch information
manwar committed Jul 28, 2020
1 parent e010836 commit f521ac6
Show file tree
Hide file tree
Showing 16 changed files with 1,803 additions and 1,349 deletions.
63 changes: 63 additions & 0 deletions challenge-071/mohammad-anwar/perl/ch-1.pl
@@ -0,0 +1,63 @@
#!/usr/bin/perl

#
# Perl Weekly Challenge - 071
#
# Task #1: Peak Elements
#
# https://perlweeklychallenge.org/blog/perl-weekly-challenge-071
#

use strict;
use warnings;

my $S = $ARGV[0] || 10;
my $array = get_random_array($S);
my $peak_elements = get_peak_elements($array);

print sprintf("Array: [%s]\n", join(", ", @$array));
print sprintf(" Peak: [%s]\n", join(", ", @$peak_elements));

#
#
# METHODS

sub get_peak_elements {
my ($array) = @_;

my @peak_elements = ();
if ($#$array >= 2 ) {

if ($array->[0] > $array->[1]) {
push @peak_elements, $array->[0];
}

for my $i (1 .. $#$array-1) {
push @peak_elements, $array->[$i]
if (($array->[$i] > $array->[$i-1])
&& ($array->[$i] > $array->[$i+1]));
}

if ($array->[-1] > $array->[-2]) {
push @peak_elements, $array->[-1];
}
}

return \@peak_elements;
}

sub get_random_array {
my ($size) = @_;

my $min = 1;
my $max = 50;
my %elements = ();
while ($size >= 1) {
my $e = $max - int(rand($min + $max));
next if (exists $elements{$e});
$elements{$e} = 1;
$size--;
}

return [ keys %elements ];
}
84 changes: 84 additions & 0 deletions challenge-071/mohammad-anwar/perl/ch-1a.pl
@@ -0,0 +1,84 @@
#!/usr/bin/perl

#
# Perl Weekly Challenge - 071
#
# Task #1: Peak Elements
#
# https://perlweeklychallenge.org/blog/perl-weekly-challenge-071
#

use strict;
use warnings;

use Test::More;
use Test::Deep;

my %test_cases = (
'test case 1' => {
in => [19, 8, 22, 11, 50, 34, 39, 48, 12, 33],
out => [19, 22, 50, 48, 33],
},
'test case 2' => {
in => [26, 39, 23, 16, 30, 4, 49, 42, 12, 14],
out => [39, 30, 49, 14],
},
'test case 3' => {
in => [20, 24, 22, 48, 49, 23, 39, 10, 14, 43],
out => [24, 49, 39, 43],
},
);

foreach my $test (keys %test_cases) {
is_deeply(
get_peak_elements($test_cases{$test}->{in}),
$test_cases{$test}->{out},
$test
);
}

done_testing;

#
#
# METHODS

sub get_peak_elements {
my ($array) = @_;

my @peak_elements = ();
if ($#$array >= 2 ) {

if ($array->[0] > $array->[1]) {
push @peak_elements, $array->[0];
}

for my $i (1 .. $#$array-1) {
push @peak_elements, $array->[$i]
if (($array->[$i] > $array->[$i-1])
&& ($array->[$i] > $array->[$i+1]));
}

if ($array->[-1] > $array->[-2]) {
push @peak_elements, $array->[-1];
}
}

return \@peak_elements;
}

sub get_random_array {
my ($size) = @_;

my $min = 1;
my $max = 50;
my %elements = ();
while ($size >= 1) {
my $e = $max - int(rand($min + $max));
next if (exists $elements{$e});
$elements{$e} = 1;
$size--;
}

return [ keys %elements ];
}
98 changes: 98 additions & 0 deletions challenge-071/mohammad-anwar/perl/ch-2.pl
@@ -0,0 +1,98 @@
#!/usr/bin/perl

#
# Perl Weekly Challenge - 071
#
# Task #2: Trim Linked List
#
# https://perlweeklychallenge.org/blog/perl-weekly-challenge-071/
#

package Node;

use Moo;

has v => (is => 'rw');
has p => (is => 'rw');

sub trim {
my ($self, $position) = @_;

my $tail = $self;
my $count = 1;
my $node;

while ($tail->p) {
if ($position > $count) {
$node = $tail;
}
elsif ($position == $count) {
if (defined $node) {
# Remove current node by making the
# parent of current node as parent
# of previous node
$node->p($tail->p);
}
else {
# If you're taking first from the end
# then return the parent of last node
return $tail->p;
}
}

$tail = $tail->p;
$count++;
}

# Take the first node off if and only if:
# a) you reached the first node or
# b) given position is more than the total nodes
$node->p(undef) if ($count <= $position);

return $self;
}

sub show {
my ($self) = @_;

my $node = $self;
my @v = ();
while ($node->p) {
push @v, $node->v;
$node = $node->p;
}
push @v, $node->v;

return join ' -> ', reverse @v;
}

package main;

my $L = $ARGV[0] || '1 -> 2 -> 3 -> 4 -> 5';
my $N = $ARGV[1] || 2;
print make_linked_list($L)->trim($N)->show, "\n";

#
#
# METHOD

sub make_linked_list {
my ($list) = @_;

$list =~ s/\s+//g;
die "ERROR: Invalid list [$list].\n"
if ($list !~ /\-\>/);

$list = [ split /\-\>/, $list ];
my $node = Node->new(v => pop @$list);

# prepare singly linked list
my $tail = $node;
while (@$list) {
my $node = Node->new(v => pop @$list);
$tail->p($node);
$tail = $node;
}

return $node;
}
116 changes: 116 additions & 0 deletions challenge-071/mohammad-anwar/perl/ch-2a.pl
@@ -0,0 +1,116 @@
#!/usr/bin/perl

#
# Perl Weekly Challenge - 071
#
# Task #2: Trim Linked List
#
# https://perlweeklychallenge.org/blog/perl-weekly-challenge-071/
#

package Node;

use Moo;

has v => (is => 'rw');
has p => (is => 'rw');

sub trim {
my ($self, $position) = @_;

my $tail = $self;
my $count = 1;
my $node;

while ($tail->p) {
if ($position > $count) {
$node = $tail;
}
elsif ($position == $count) {
if (defined $node) {
# Remove current node by making the
# parent of current node as parent
# of previous node
$node->p($tail->p);
}
else {
# If you're taking first from the end
# then return the parent of last node
return $tail->p;
}
}

$tail = $tail->p;
$count++;
}

# Take the first node off if and only if:
# a) you reached the first node or
# b) given position is more than the total nodes
$node->p(undef) if ($count <= $position);

return $self;
}

sub show {
my ($self) = @_;

my $node = $self;
my @v = ();
while ($node->p) {
push @v, $node->v;
$node = $node->p;
}
push @v, $node->v;

return join ' -> ', reverse @v;
}

package main;

use Test::More;

my $list = '1 -> 2 -> 3 -> 4 -> 5';
my %test_cases = (
'testing $N = 1' => { n => 1, o => '1 -> 2 -> 3 -> 4' },
'testing $N = 2' => { n => 2, o => '1 -> 2 -> 3 -> 5' },
'testing $N = 3' => { n => 3, o => '1 -> 2 -> 4 -> 5' },
'testing $N = 4' => { n => 4, o => '1 -> 3 -> 4 -> 5' },
'testing $N = 5' => { n => 5, o => '2 -> 3 -> 4 -> 5' },
'testing $N = 6' => { n => 6, o => '2 -> 3 -> 4 -> 5' },
);

foreach my $test (sort keys %test_cases) {
is(
make_linked_list($list)->trim($test_cases{$test}->{n})->show,
$test_cases{$test}->{o},
$test
);
}

done_testing;

#
#
# METHOD

sub make_linked_list {
my ($list) = @_;

$list =~ s/\s+//g;
die "ERROR: Invalid list [$list].\n"
if ($list !~ /\-\>/);

$list = [ split /\-\>/, $list ];
my $node = Node->new(v => pop @$list);

# prepare singly linked list
my $tail = $node;
while (@$list) {
my $node = Node->new(v => pop @$list);
$tail->p($node);
$tail = $node;
}

return $node;
}

0 comments on commit f521ac6

Please sign in to comment.