From 0a842e6c7df97d70d075d08e4520a6b2bf4d50f2 Mon Sep 17 00:00:00 2001 From: Jörg Sommrey <28217714+jo-37@users.noreply.github.com> Date: Mon, 11 Jan 2021 14:07:16 +0100 Subject: Solution to task 1 --- challenge-095/jo-37/perl/ch-1.pl | 113 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100755 challenge-095/jo-37/perl/ch-1.pl diff --git a/challenge-095/jo-37/perl/ch-1.pl b/challenge-095/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..f3c19491d6 --- /dev/null +++ b/challenge-095/jo-37/perl/ch-1.pl @@ -0,0 +1,113 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0; +use warnings FATAL => 'all'; +use Scalar::Util 'looks_like_number'; +use experimental 'signatures'; + +our ($tests, $examples, $verbose); + +run_tests() if $tests || $examples; # does not return + +say(<stringify->reverse->numify->stringify +# resembles the input string. (All transformations from a Perl view.) +# +# This sub uses different false return values to signal the failed test: +# - undef for a non-numeric input string +# - the empty string for a non-numeric reversed numified input string +# - zero for a numeric forward and backward value that is not a palindrome +# number +sub palindrome_number ($str) { + return unless looks_like_number $str; + my $reverse = reverse $str + 0; + return '' unless looks_like_number $reverse; + + 0 + ($str eq $reverse + 0); +} + +### Examples and tests + +sub run_tests { + SKIP: { + skip "examples" unless $examples; + ok palindrome_number(1221), 'example 1: 1221 is palindrome'; + ok !palindrome_number(-101), 'example 2: -101 is not palindrome'; + ok !palindrome_number(90), 'example 3: 90 is not palindrome'; + } + + SKIP: { + skip "tests" unless $tests; + for my $str (qw(21e12 1.221e3 0012100 00121 0012.2100)) { + ok !palindrome_number($str), "$str is not palindrome"; + } + for my $str (qw(12.21 1221)) { + ok palindrome_number($str), "$str is palindrome"; + } + + # specific return codes + is palindrome_number('1O2O1'), U(), 'not a number'; + is palindrome_number('-101'), '', 'reverse not a number'; + is palindrome_number('1e-21'), '', 'reverse not a number'; + is palindrome_number('12327'), 0, 'not palindrome'; + is palindrome_number('+121.0'), 0, 'not palindrome'; + is palindrome_number('121'), 1, 'palindrome'; + + # exotic cases: NaN vs. nan + is palindrome_number('NaN'), 0, 'NaN is numeric'; + is palindrome_number('nan'), 1, 'possibly the strangest case'; + } + + done_testing; + exit; +} -- cgit From 6c76a50e6a33bd0881dd9021243b71607fe72841 Mon Sep 17 00:00:00 2001 From: Jörg Sommrey <28217714+jo-37@users.noreply.github.com> Date: Mon, 11 Jan 2021 14:39:21 +0100 Subject: Solution to task 2 --- challenge-095/jo-37/perl/ch-2.pl | 158 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100755 challenge-095/jo-37/perl/ch-2.pl diff --git a/challenge-095/jo-37/perl/ch-2.pl b/challenge-095/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..693759a17d --- /dev/null +++ b/challenge-095/jo-37/perl/ch-2.pl @@ -0,0 +1,158 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0; +use warnings FATAL => 'all'; +use experimental 'signatures'; + +our ($tests, $examples, $verbose); + +$Stack::verbose = 1 if $verbose; + +run_tests() if $tests; # does not return + +# prepare example run +unshift @ARGV, 'ch-2-ex.pl' if $examples; + +say(< sub {push @stack, $arg}, # returns new stack size + pop => sub {pop @stack}, # returns removed element + top => sub {$stack[$#stack]}, + min => sub {List::Util::min @stack}, + max => sub {List::Util::max @stack}, + size => sub {@stack}, # returns current stack size + clear => sub {splice @stack}, # returns top element + ); + + # Wrapping the "base" functionality in an object. For this purpose + # override "can" to return an existing or generated $method. Must + # be available at compile time. + sub can ($self, $method) { + # Retrieve parent methods as well as the defined methods + # of this class. + my $can = $self->SUPER::can($method); + return $can if $can; + + my $call = $method{$method}; + return unless $call; + + # Generate a method to perform the configured call. + sub ($self, $val=undef) { + # Provide variables and call method sub. + local $arg = $val; + local *stack = $self; # make @$self available as @stack + my $result = &$call(); + + # Benefit from method generation: single code for every + # method. + no warnings 'uninitialized'; + say "$method($val): $result" if $verbose; + + $result; + } + } +} + +# Autoload dynamic methods +our $AUTOLOAD; +sub AUTOLOAD ($self, @args) { + my $called = $AUTOLOAD =~ s/.*:://r; + my $method = $self->can($called); + croak qq{Can't locate object method "$called" via package "} + . __PACKAGE__ . '"' unless $method; + + $self->$method(@args); +} + +# Creates an empty Stack. +sub new ($class) { + bless [], $class; +} + + +### Tests + +package main; + +sub run_tests { + my $stack = Stack->new; + + is $stack->size, 0, 'empty'; + is $stack->min, U(), 'no min from empty stack'; + is $stack->max, U(), 'no max from empty stack'; + is $stack->top, U(), 'no top from empty stack'; + is $stack->pop, U(), 'no pop from empty stack'; + is $stack->push(2), 1, '1 element on stack'; + is $stack->size, 1, 'after first push'; + is $stack->push(-1), 2, '2 elements on stack'; + is $stack->size, 2, 'after second push'; + is $stack->push(0), 3, '3 elements on stack'; + is $stack->size, 3, 'after third push'; + is $stack->pop, 0, 'pop'; + is $stack->size, 2, 'after pop'; + is $stack->top, -1, 'top'; + is $stack->push(0), 3, '3 elements on stack'; + is $stack->size, 3, 'after fourth push'; + is $stack->min, -1, 'minimum'; + is $stack->max, 2, 'maximum'; + is $stack->clear, 0, 'clear stack'; + is $stack->size, 0, 'empty stack'; + + SKIP: { + $stack->push(-1); + ok my $can = $stack->can('can'), 'inquires parent for "can"' + or skip 'cannot can'; + ok my $pop = $stack->$can('pop'), 'retrieve "pop" ref' + or skip 'cannot pop'; + is $stack->$pop, -1, 'invoke "pop" ref'; + } + like dies {$stack->foo}, qr/Can't locate object method/, 'method missing'; + + done_testing; + exit; +} -- cgit From 13eb7ac802214f8dbd47270979f506d007acde3e Mon Sep 17 00:00:00 2001 From: Jörg Sommrey <28217714+jo-37@users.noreply.github.com> Date: Mon, 11 Jan 2021 17:49:11 +0100 Subject: Example script for task 2 --- challenge-095/jo-37/perl/ch-2-ex.pl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 challenge-095/jo-37/perl/ch-2-ex.pl diff --git a/challenge-095/jo-37/perl/ch-2-ex.pl b/challenge-095/jo-37/perl/ch-2-ex.pl new file mode 100644 index 0000000000..ec63be8f36 --- /dev/null +++ b/challenge-095/jo-37/perl/ch-2-ex.pl @@ -0,0 +1,19 @@ +use v5.16; + +# Let "Stack" print calls and results +$Stack::verbose = 1; + +say 'create Stack'; +my $stack = Stack->new; + +$stack->push(2); +$stack->push(-1); +$stack->push(0); +$stack->pop; +$stack->top; +$stack->push(0); + +$stack->min; + +$stack->max; +$stack->size; -- cgit