Perl Weekly Challenge: Week 95

Challenge 1:

Palindrome Number

You are given a number $N.

Write a script to figure out if the given number is Palindrome. Print 1 if true otherwise 0.

Example 1
Input: 1221
Output: 1
Example 2
Input: -101
Output: 0, since -101 and 101- are not the same.
Example 3
Input: 90
Output: 0

Never mind that the spec mentions a number; we can treat the input as a string making solving this is a one-liner. In Perl:

say $ARGV[0] eq reverse($ARGV[0]) ? 1 : 0;

(Full code on Github.)

...and in Raku:

say @*ARGS[0] eq @*ARGS[0].flip ?? 1 !! 0;

(Full code on Github.)

In both cases, I ran this code from the command line wrapped in a shell script. I found that running example 2 on the perl version gave an error because it looks like a command line switch. The workaround was to quote the input on the command line like this: \\-90. Raku doesn't have this problem.

Challenge 2:

Demo Stack

Write a script to demonstrate Stack operations like below:

Example:

Example 1
my $stack = Stack->new;
$stack->push(2);
$stack->push(-1);
$stack->push(0);
$stack->pop;       # removes 0
print $stack->top; # prints -1
$stack->push(0);
print $stack->min; # prints -1

A stack is a fundamental data type in Computer Science although you really don't need it in Perl where you have associative arrays. In fact the stack class I show here is just a thin wrapper around associative arrays.

package Data::Stack;
use Moo;

Normally for these challenges I don't use external modules relying on what is built into Perl or Raku. But for this challenge I need to create a class and when I do OOP in Perl I prefer to use the [Moo](https://metacpan.org/pod/Moo) module rather than Perls' builtin facilities as it smoother to use and has more of the features you would expect from an object oriented framework.

use List::Util;

As I'm using extra modules anyway, I might as well use this one too as it has a min() routine I will be using later as we shall see.

use namespace::clean;

This is recommended with Moo for removing any extra cruft such as imported subroutines from your scripts.

has _stack => (
    is => 'rw',
    default => sub { [] }
);

The class has one data member, _stack with is a reference to an array. We tell Moo it can be modified.

sub push {
    my ($self, $value) = @_;

    return push @{$self->_stack}, $value;
}

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

    return pop @{$self->_stack};
}

These methods just do normal Perl push() and pop() on _stack. The stack is modeled as growing from left to write so adding or removing an element from the end of _stack is equivalent to adding or removing an element from the 'top' of the stack.

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

    return $self->_stack->[-1];
}

This method returns the last element of _stack which is the 'top' of the stack.

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

    return List::Util::min( @{$self->_stack} );
}

This method returns the minimum value on the stack. As I mentioned before I am using the min() routine from List::Util but because this method is also called min() I have to fully qualify the name in order to use it.

(Full code on Github.)

Raku has sensible OOP features builtin. The class and method keywords are just syntactic sugar really, but something truly important is the ! 'twigil' which enables proper encapsulation of data members. This is something you just can't do in Perl.

class Data::Stack {

    has Int @!stack = ();

    method push(Any $n) {
        @!stack.push($n);
    }

    method pop() {
        return @!stack.pop;
    }

    method top() {
        return @!stack.tail;
    }

.tail() gives you the last element of an array. It is equivalent to [*-1] but just slightly easier to read.

    method min() {
        return @!stack.min;
    }

.min() is a builtin method of arrays so there is no need to bring in another module.

}

(Full code on Github.)