# Perl Weekly Challenge 95.

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
``````

Instead of checking if a number is a palindrome, I will test if an arbitrary string is a palindrome. I simply reverse the string and compare it to the original.

``````# Perl weekly challenge 095
# Figure out if a number is a palindrome.
use v5.12;
use strict;
use warnings;
say("Input: \$_\nOutput:", ("\$_" eq reverse "\$_")?1:0) foreach @ARGV;

./ch-1.pl 1221 -101 90
``````

Results:

``````Input: 1221
Output:1
Input: -101
Output:0
Input: 90
Output:0
``````

This is small enough to be made into a oneliner.

``````perl -E 'say("Input: \$_\nOutput:", ("\$_" eq reverse "\$_")?1:0) foreach @ARGV' 1221 -101 90;
``````

Results:

``````Input: 1221
Output:1
Input: -101
Output:0
Input: 90
Output:0
``````

Finally, I make a small variation to remove all punctuation and use lowercase before making the comparison, to test actual palindromes. In this case, I receive the text from `STDIN`.

``````# Perl weekly challenge 095
# Task 1: Palindrome number. Alternative solution
# Figure out if a string is a palindrome after stripping punctuation.
use v5.12;
use strict;
use warnings;
use English;
undef \$INPUT_RECORD_SEPARATOR;
my \$input=<>;
(my \$clean_input=lc \$input)=~s/\W//g;
say("Input:\n\$input\nOutput:", ("\$clean_input" eq reverse "\$clean_input")?1:0);
``````

Example: A children’s palindrome in Spanish:

``````./ch-1a.pl <<FIN
Anita
lava la
tina.
FIN
``````

Results:

``````Input:
Anita
lava la
tina.

Output:1
``````

Example: One of Merlina Acevedo’s recent palindromes.

``````./ch-1a.pl <<EOF
Evil alive's in a man
is a fool, an aloof,
as in a man, is evil
lives in a bar,
a wall
a wiz
a nazi wall,
as in a tan,
ill in a dumb mob
as a bomb
Mud,
an ill in a tan is all:
a wiz
a nazi wall,
a war
a ban
Is evil,
lives in a man,
is a fool, an aloof,
As in a man,
Is evil alive?
EOF
``````

Results:

``````Input:
Evil alive's in a man
is a fool, an aloof,
as in a man, is evil
lives in a bar,
a wall
a wiz
a nazi wall,
as in a tan,
ill in a dumb mob
as a bomb
Mud,
an ill in a tan is all:
a wiz
a nazi wall,
a war
a ban
Is evil,
lives in a man,
is a fool, an aloof,
As in a man,
Is evil alive?

Output:1
``````

I found that `\W` gets confused by some punctuation marks, such as the opening question mark ‘¿’ or some quotes ‘´’. I guess I would have to set the adequate locale for it to work with these characters.

Write a script to demonstrate Stack operations like below:

`push(\$n)` - add \$n to the stack `pop()` - remove the top element `top()` - get the top element `min()` - return the minimum element

``````Example:
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
``````

I make a stack class using Moo and an array for the data. I prints the stack everytime it changes and I print the on-going operation.

``````# Perl weekly challenge 095
# Demonstrate Stack operations.
package Stack;
use List::Util;
use v5.12;
use Moo;
has _stack=>(is=>'ro', default=>sub{[]}, init_arg=>undef);
sub push {
my \$self=shift;
my \$x=shift;
say "Push:\t\$x";
my \$s=\$self->_stack;
push @\$s, \$x;
\$self->show;
}
sub pop {
my \$self=shift;
my \$s=\$self->_stack;
die "Empty stack" unless defined \$s;
my \$top=pop @\$s;
say "Pop:\t\$top";
\$self->show;
return \$top;
}
sub top {
my \$self=shift;
my \$top=\$self->_stack->[-1];
say "Top:\t\$top";
return \$top;
}
sub exch {
my \$self=shift;
my \$x=\$self->pop;
my \$y=\$self->pop;
say "Exch:\t\$x <-> \$y";
\$self->push(\$x);
\$self->push(\$y);
}
sub min {
my \$self=shift;
my \$s=\$self->_stack;
my \$min=List::Util::min @\$s;
say "Min:\t\$min";
\$self->push(\$min);
}
sub max {
my \$self=shift;
my \$s=\$self->_stack;
my \$max=List::Util::max @\$s;
say "Max:\t\$max";
\$self->push(\$max);
}
my \$self=shift;
my (\$x, \$y)=(\$self->pop,\$self->pop);
my \$res=\$x+\$y;
say "Add:\t\$x + \$y -> \$res";
\$self->push(\$res);
}
sub sub {
my \$self=shift;
my (\$x, \$y)=(\$self->pop,\$self->pop);
my \$res=\$y-\$x;
say "Sub:\t\$y - \$x -> \$res";
say "Sub:\t\$res";
\$self->push(\$res);
}
sub mul {
my \$self=shift;
my (\$x, \$y)=(\$self->pop,\$self->pop);
my \$res=\$x*\$y;
say "Mul:\t\$x * \$y -> \$res";
\$self->push(\$res);
}
sub div {
my \$self=shift;
my (\$x, \$y)=(\$self->pop,\$self->pop);
my \$res=\$y/\$x;
say "Div:\t\$y / \$x -> \$res";
\$self->push(\$res);
}
sub cs {
my \$self=shift;
my \$x=\$self->pop;
my \$res=-\$x;
say "CS:\t\$x -> \$res";
\$self->push(\$res);
}
sub inv {
my \$self=shift;
my \$x=\$self->pop;
my \$res=1/\$x;
say "Inv:\t1/\$x -> \$res";
\$self->push(\$res);
}
sub show {
my \$self=shift;
my \$s=\$self->_stack;
say "Stack:\t", join " ", reverse @\$s;
}
``````

Drive the package from `STDIN`. I use a simple RPN notation to make a primitive calculator. Numbers are pushed, operators operate on the top operands of the stack.

``````package main;
use Scalar::Util qw(looks_like_number);
my \$s=Stack->new;
while(<>){
chomp;
\$s->push(\$_), next if looks_like_number(\$_);
\$s->pop, next if lc \$_ eq "pop";
\$s->top, next if lc \$_ eq "top";
\$s->exch, next if lc \$_ eq "exch";
\$s->min, next if lc \$_ eq "min";
\$s->max, next if lc \$_ eq "max";
\$s->add, next if \$_ eq "+";
\$s->sub, next if lc \$_ eq "-";
\$s->mul, next if lc \$_ eq "*";
\$s->div, next if lc \$_ eq "/";
\$s->cs, next if lc \$_ eq "cs"; # change sign
\$s->inv, next if lc \$_ eq "inv"; # invert
\$s->show, next if lc \$_ eq "show";
die "Unrecognized op";
}
``````

Example:

``````./ch-2.pl <<EOF
2
-1
0
pop
top
0
min
EOF
``````

Results:

``````Push:	2
Stack:	2
Push:	-1
Stack:	-1 2
Push:	0
Stack:	0 -1 2
Pop:	0
Stack:	-1 2
Top:	-1
Push:	0
Stack:	0 -1 2
Min:	-1
Push:	-1
Stack:	-1 0 -1 2
``````

Another example:

``````./ch-2.pl <<EOF #5/2*2-5=0
2
5
exch
/
2
*
5
-
EOF
``````

Results:

``````Push:	2
Stack:	2
Push:	5
Stack:	5 2
Pop:	5
Stack:	2
Pop:	2
Stack:
Exch:	5 <-> 2
Push:	5
Stack:	5
Push:	2
Stack:	2 5
Pop:	2
Stack:	5
Pop:	5
Stack:
Div:	5 / 2 -> 2.5
Push:	2.5
Stack:	2.5
Push:	2
Stack:	2 2.5
Pop:	2
Stack:	2.5
Pop:	2.5
Stack:
Mul:	2 * 2.5 -> 5
Push:	5
Stack:	5
Push:	5
Stack:	5 5
Pop:	5
Stack:	5
Pop:	5
Stack:
Sub:	5 - 5 -> 0
Sub:	0
Push:	0
Stack:	0
``````

Yet another example:

``````./ch-2.pl <<EOF # -1/(1+5-4)*4/2)*4=-1
1
5
+
4
-
4
*
2
/
inv
cs
4
*
EOF
``````

Results:

``````Push:	1
Stack:	1
Push:	5
Stack:	5 1
Pop:	5
Stack:	1
Pop:	1
Stack:
Add:	5 + 1 -> 6
Push:	6
Stack:	6
Push:	4
Stack:	4 6
Pop:	4
Stack:	6
Pop:	6
Stack:
Sub:	6 - 4 -> 2
Sub:	2
Push:	2
Stack:	2
Push:	4
Stack:	4 2
Pop:	4
Stack:	2
Pop:	2
Stack:
Mul:	4 * 2 -> 8
Push:	8
Stack:	8
Push:	2
Stack:	2 8
Pop:	2
Stack:	8
Pop:	8
Stack:
Div:	8 / 2 -> 4
Push:	4
Stack:	4
Pop:	4
Stack:
Inv:	1/4 -> 0.25
Push:	0.25
Stack:	0.25
Pop:	0.25
Stack:
CS:	0.25 -> -0.25
Push:	-0.25
Stack:	-0.25
Push:	4
Stack:	4 -0.25
Pop:	4
Stack:	-0.25
Pop:	-0.25
Stack:
Mul:	4 * -0.25 -> -1
Push:	-1
Stack:	-1
``````
Written on January 11, 2021