## Perl Weekly Challenge 95: Palindrome Numbers and Demo Stack

These are some answers to the Week 95 of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few of days (January 17, 2021). This blog post offers some solutions to this challenge, please don’t read on if you intend to complete the challenge on your own.

## Task 1: Palindrome Numbers

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

A palindrome is a word, number, phrase, or other sequence of characters which reads the same backward as forward, like “noon”, “madam”, or “redivider”.

## Palindrome Numbers in Raku

This is fairly simple. We just compare the input with its reversed version:

``````use v6;

my \$num = @*ARGS[0] // 1221;
say "\$num: ", +(\$num eq \$num.flip);
``````

Note that the `+` sign in the second code line is aimed at numifying the value of the Boolean expression `\$num eq \$num.flip` (`False` or `True`) into 0 or 1.

This is the output with a few input values:

``````\$ raku palindrome.raku
1221: 1

\$ raku palindrome.raku 7337
7337: 1

\$ raku palindrome.raku 8765
8765: 0

\$ raku palindrome.raku -1221
-1221: 0
``````

This is so simple that we can also do it as a one-liner script:

``````\$ raku -e 'my \$n = @*ARGS[0]; say "\$n: ", +(\$n eq \$n.flip);' 7337
7337: 1
``````

## Palindrome Numbers in Perl

Again, we just compare the input with its reversed version:

``````use strict;
use warnings;
use feature "say";

my \$num = shift // 1221;
say "\$num: ", \$num eq (reverse \$num) ? 1 : 0;
``````

This is the output with a few input values:

``````\$ perl palindrome.pl
1221: 1

\$ perl palindrome.pl 7337
7337: 1

\$ perl palindrome.pl 5678
5678: 0

\$ perl palindrome.pl -101
-101: 0
``````

We can also do a Perl one-liner:

``````\$ perl -E '\$n = shift; say "\$n: ", \$n eq (reverse \$n) ? 1 : 0;' 1221
1221: 1
``````

## Palindrome Numbers in Scala

The Scala version uses essentially the same idea:

``````object Main {
def main(args: Array[String]): Unit = {
val num = args(0).toString
if (num == num.reverse) {
println(1)
} else {
println(0)
}
}
}
``````

This Scala program produces the same results as the above Raku and Perl programs.

## Task 2: Demo Stack

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

There are already `push` and `pop` built-in functions in both Raku and Perl, so we will give our stack operations different names. The stack will be implemented as a simple array with the relevant stack operations.

### Demo Stack in Raku

#### Functional Implementation

Implementing a stack is typical of a job for object-oriented programming. However, I will start with a more functional approach (as I prefer that). The `push` and `pop` stack operations are renamed `put-in-stack` and `take-from-stack`:

``````use v6;

sub put-in-stack (@stack, *@new-items) {
push @stack, |@new-items;
}
sub take-from-stack (@stack where @stack.elems > 0) {
return pop @stack;
}
sub top (@stack where @stack.elems > 0) {
return @stack.tail;
}
sub minimum (@stack where @stack.elems > 0) {
return @stack.min;
}
my @a-stack = 1..5;
say @a-stack;
put-in-stack @a-stack, 6..8;
say @a-stack;
say "Min: ", minimum @a-stack;
say "Top: ", top @a-stack;
say "Take: ", take-from-stack @a-stack;
say @a-stack;
``````

This displays the following output:

``````\$ raku stack_oo.raku
[1 2 3 4 5]
[1 2 3 4 5 6 7 8]
Min: 1
Top: 8
Take: 8
[1 2 3 4 5 6 7]
``````

#### Object-Oriented Implementation

If you prefer an object-oriented version, it could look like this:

``````use v6;

class Stack {
has @.stack is rw;
method is-empty {
@!stack.elems > 0 ?? False !! True;
}
method put-in-stack (*@new-items) {
push @!stack, |@new-items;
}
method take-from-stack {
return pop @!stack;
}
method top {
return @!stack.tail;
}
method minimum {
return @!stack.min;
}
}
my \$a-stack = Stack.new( stack => 1..5);
say \$a-stack.stack;
\$a-stack.put-in-stack: 6..8;
say \$a-stack.stack;
say "Min: ", \$a-stack.minimum;
say "Top: ", \$a-stack.top;
say "Take: ", \$a-stack.take-from-stack ;
say \$a-stack.stack;
``````

The code using the `Stack` class should really check that the stack is not empty (with the `is-empty` method) before calling the `take-from-stack`, `top`, or `minimum` methods to avoid an unhandled exception, and we may in that case raise an ad-hoc exception or print an error message or do something else, but since we have no specification on what to do in such a case, this is left as an exercise to the reader.

Output:

``````\$ raku  stack_oo.raku
[1 2 3 4 5]
[1 2 3 4 5 6 7 8]
Min: 1
Top: 8
Take: 8
[1 2 3 4 5 6 7]
``````

### Demo Stack in Perl

In Perl, we will implement only the functional version:

``````#!/usr/bin/perl
use strict;
use warnings;
use feature qw/say/;

sub is_empty {
my \$stack = shift;
return @\$stack > 0 ? 0 : 1;
}

sub put_in_stack {
my (\$stack, @new_items) = @_;
push @\$stack, @new_items;
}
sub take_from_stack  {
my \$stack = shift;
return undef if is_empty \$stack;
return pop @\$stack;
}
sub top {
my \$stack = shift;
return undef if is_empty \$stack;
return \$stack->[-1];
}
sub minimum {  # assuming stack of numeric values
my \$stack = shift;
return undef if is_empty \$stack;
my \$min = \$stack->[0];
for my \$item (@\$stack) {
\$min = \$item if \$item < \$min;
}
return \$min;
}
my \$a_stack = [1..5];
say "@\$a_stack";
put_in_stack \$a_stack, 6..8;
say "@\$a_stack";
say "Min: ", minimum \$a_stack;
say "Top: ", top \$a_stack;
say "Take: ", take_from_stack \$a_stack;
say "@\$a_stack";
``````

This displays the following output:

``````\$ perl stack.pl
1 2 3 4 5
1 2 3 4 5 6 7 8
Min: 1
Top: 8
Take: 8
1 2 3 4 5 6 7
``````

### Demo Stack in Scala

Being a beginner in Scala, I don’t yet master passing function parameters by value or by reference. So I’ll make my stack a global variable to enable in-place modification. You don’t need to tell me it’s bad, I know. At this point, I’m only trying to make a program that works properly, I’ll hopefully implement better practices and write more idiomatic Scala code in a few months from now.

``````object stack extends App {
var stack = Array(1, 2, 3, 4, 5)
print_stack("Original stack")
push(Array(6, 7, 8))
print_stack("Pushed stack")
val popped = pop
println(s"Popped: \$popped")
print_stack("Popped stack")
val topped = top
println(s"Top: \$topped")
val minimum = min
println(s"Min: \$minimum")
def print_stack(caption: String) : Unit = {
print(s"\$caption: "); println( stack.mkString(" "))
}
def push(newItems: Array[Int]): Unit = {
stack ++= newItems
}
def pop: Int = {
val lastItem = stack.last
stack = stack.dropRight(1)
return lastItem
}
def top: Int = {
return stack.last
}
def min: Int = {
var min = stack(0);
for (i <- 1 to (stack.length - 1)) {
if (stack(i) < min) min = stack(i)
}
return min
}
}
``````

This displays the following output:

``````Original stack: 1 2 3 4 5
Pushed stack: 1 2 3 4 5 6 7 8
Popped: 8
Popped stack: 1 2 3 4 5 6 7
Top: 7
Min: 1
``````

## Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on Sunday, January 17, 2021. And, please, also spread the word about the Perl Weekly Challenge if you can.

## Leave a comment

### About laurent_r

I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.