Perl: the Markov chain saw PerlMonks

### Palindrome array

by rnaeye (Pilgrim)
 on Dec 29, 2012 at 05:35 UTC ( #1010790=perlquestion: print w/ replies, xml ) Need Help??
rnaeye has asked for the wisdom of the Perl Monks concerning the following question:

Hi! Monks,
Why does the first code work, but not the second one? Can you help me understand. Thank you!

```
#!/usr/bin/perl
use warnings;
use strict;
use 5.010;

my @array = qw(x a m a x);
my @reversed = reverse @array;
if (@array eq @reversed){
say "this's a palindrome.";
} else {
say "this's not a palindrome";
}
```
#!/usr/bin/perl
use warnings;
use strict;
use 5.010;

my @array = qw(x a m a x);
if (@array eq (reverse @array)){
say "this's a palindrome.";
} else {
say "this's not a palindrome.";
}

Comment on Palindrome array
Replies are listed 'Best First'.
Re: Palindrome array
by LanX (Canon) on Dec 29, 2012 at 06:13 UTC
The ugly truth is both don't work!

eq forces scalar context and is meant to compare strings

So in the first code you are checking if the sizes (after stringification) are equal.

```  DB<107> @a = 1..3
=> (1, 2, 3)

DB<108> @a eq "3"
=> 1

in the second you have scalar from reverse on RHS

```  DB<123> (reverse @a)
=> (3, 2, 1)

DB<124> scalar (reverse @a)
=> 321

DB<125> "321" eq (reverse @a)
=> 1

you can try the (less weird) smart match operator ~~ to compare arrays.

```  DB<129> @a=(3,1,3)
=> (3, 1, 3)

DB<130> @a ~~ [reverse @a]
=> 1

DB<131> @a ~~ [3,1,3]
=> 1

DB<132> @a=1..3
=> (1, 2, 3)

DB<133> @a ~~ [reverse @a]
=> ""

a poor man's solution with eq is to explicitly stringify on both sides.

```  DB<143> @a=(3,1,3)
=> (3, 1, 3)

DB<144> @ar=reverse @a
=> (3, 1, 3)

DB<145> "@a"
=> "3 1 3"

DB<146> "@a" eq "@ar"
=> 1

But this depends on the nature of your array elements, don't be too surprised about:

```  DB<151> "@a"
=> "3 1 3"

DB<152> @b=(3,"1 3")
=> (3, "1 3")

DB<153> "@a" eq "@b"
=> 1

Cheers Rolf

Re: Palindrome array
by Athanasius (Abbot) on Dec 29, 2012 at 06:04 UTC

The string comparison operator eq puts its operands into scalar context:

```#! perl
use warnings;
use strict;
use 5.010;

say 'equal' if context('1') eq context('2');

sub context
{
my \$c = (defined wantarray) ?
(wantarray  ? 'list' : 'scalar')
: 'void';
say '(', shift, '): is in ', \$c, ' context';
return 42;
}

Output:

```15:56 >perl 457_SoPW.pl
(1): is in scalar context
(2): is in scalar context
equal

15:56 >

So, neither code snippet is doing what you want. The first compares the sizes of the two arrays. The second compares the size of @array with the value returned by reverse, which

In scalar context, concatenates the elements of LIST and returns a string value with all characters in the opposite order.

To compare the contents of the two arrays, use the smart match operator ~~. See How do I test whether two arrays or hashes are equal?

Hope that helps,

 Athanasius <°(((>< contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Palindrome array
by davido (Archbishop) on Dec 29, 2012 at 09:47 UTC

There are a number of good ways to approach this. Here's one way that uses a CPAN module:

```use String::Palindrome qw( is_palindrome );

my @array = qw( x a m a x );

print "@array ",
is_palindrome( @array ) ? "is" : "isn't ",
"palindromic.\n";

The above solution works just as well if you pass it a string rather than an array, but in either case it does the job.

Dave

Re: Palindrome array
by Jim (Curate) on Dec 29, 2012 at 09:01 UTC

This isn't C. In Perl, a palindrome is properly represented as a string, not an array of characters.

```#!perl

use strict;
use warnings;

my \$string  = "A Man, A Plan, A Canal -- Panama!";
my \$letters = lc \$string;

\$letters =~ s/\W//g;

printf qq/"%s" %s a palindrome.\n/,
\$string, \$letters eq reverse(\$letters) ? "is" : "isn't";

__END__

"A Man, A Plan, A Canal -- Panama!" is a palindrome.

If this is a homework assignment, tell your teacher you expect to be given more verisimilar programming problems. ;-)

If you're writing a Perl program to identify palindromic sequences in nucleic acids, you should still use strings, not arrays of characters, in my opinion.

Jim

Re: Palindrome array
by karlgoethebier (Vicar) on Dec 29, 2012 at 19:35 UTC

BTW, why array? I just cheated this from Re^2: palindrome using regular expressions...

```#!/usr/bin/perl
+

use strict;
use warnings;

my \$palindrome = 'lagerregal';

my \$check = reverse \$palindrome;

print "yes\n" if \$check eq \$palindrome;

\$palindrome='xamax';

\$check = reverse \$palindrome;

print "still yes\n" if \$check eq \$palindrome;

__END__

Regards, Karl

«The Crux of the Biscuit is the Apostrophe»

Re: Palindrome array
by 2teez (Priest) on Dec 29, 2012 at 05:52 UTC

"...Why does the first code work, but not the second one? Can you help me understand..."

using this

```if (@array eq (reverse scalar @array)){..
gives the result you want on the second one.
Does that help or solve the puzzle by any means?

If you tell me, I'll forget.
If you show me, I'll remember.
if you involve me, I'll understand.
--- Author unknown to me
> if (@array eq (reverse scalar @array)){..

Sorry I can't let this stand uncorrected!

```  DB<108> @array=1..9
=> (1, 2, 3, 4, 5, 6, 7, 8, 9)

DB<109> @array eq (reverse scalar @array)
=> 1

DB<110> @array=0..9
=> (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

DB<111> @array eq (reverse scalar @array)
=> ""

DB<112> scalar (reverse scalar @array)
=> "01"

DB<113> scalar @array
=> 10

Cheers Rolf

Hi LanX,

```> if (@array eq (reverse scalar @array)){..
"..Sorry I can't let this stand uncorrected!.."
There is really no need to be sorry, because your assertions and "tests" are so correct and right I.

However, I believe Athanasius first caught the message I was trying to pass to the OP, in this line
..The string comparison operator eq puts its operands into scalar context..

++ LanX

I -> Updated.

If you tell me, I'll forget.
If you show me, I'll remember.
if you involve me, I'll understand.
--- Author unknown to me

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1010790]
Approved by Athanasius
Front-paged by 2teez
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (19)
As of 2015-08-28 15:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?