chinamox has asked for the wisdom of the Perl Monks concerning the following question:

Hello again all,

I am working of a project that has me looking for palindromes. So far I have sussed out this much:

use strict; use warnings; my $palindrome = 'anna'; my $test = reverse $palindrome; print "$palindrome is a palindrome. \n" if $test = $palindrome;

I have two major challenges left.

First, as per Chargrill's point below, I think I need to delete all the white space to make sure I don't get 'A Danish custard--drat such sin, Ada's back at me.

Second, I only want to find palindromes with the lengnth of four characters or more , so 'bob' should not be printed.

Third, I need it to ignore capital letters, so 'Anna' should be printed. Is there a way to slap an 'i' on the back of this script or must I resort to a regex? Could this be combined with getting rid of white spaces?

Thanks for any pointers and your time!

-mox

Replies are listed 'Best First'.
Re: Improving a palindrome script...
by chargrill (Parson) on Oct 24, 2006 at 18:48 UTC

    Just a note, you may also with to remove anything that isn't a letter and convert all letters to either uppercase or lowercase for comparison. Because, after all, phrases like:

    • Jarred arts sell less, Trader Raj!
    • A Danish custard--drat such sin, Ada
    • O, Lisa sees a silo!
    • etc...

    ... are all palindromes. See here for more fun with palindromes.



    --chargrill
    s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)
      A little off topic, but ...

      I learned a long time ago that in Japanese they use a slightly different concept of "palindrome".

      Since the Japanese language uses syllables (eg. "a", "i", "u", "ka", "ki", "ku", "sa", "shi", "su", etc.) instead of individual letters, their "palindromes" are made up of phrases in which the individual syllables can be read the same way forwards and backwards:

      Kankei nai kenka (= ka n ke i na i ke n ka) English: "an unrelat +ed argument" Natsu made matsu na (= na tsu ma de ma tsu na) English: "don't wait + until summer"
      And even though it's not a palindrome, if you ask a Japanese person to say the word "tebukuro" (English = "glove") backwards, it comes out as "rokubute", which means "hit me 6 times", at which point you emphasize the joke by punching them on the arm.

      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

        *laughs with joy and runs down the linguistic rabbit hole…*

        As I speak a decent amount of Mandarin I know all about odd Asian word humor. The Chinese language also uses syllables (which are represented by one character for each syllables) Because Mandarin and most of the dialects focus on using tones to distinguish between two characters pronounced "ma" in English, allot of Chinese linguistic humor comes from fudging the ton or conflating characters. This will happen at all levels of society at all levels of humor.

        This might be important to anyone working on an international website because the Chinese often use numbers to make simple puns in things like usernames and , stupidly enough, passwords.

        51 = ‘wuyao’ I want =’woyao’ Hence the popular website: www.51job.com

        If you are really good, you can make a phonetic and tonal palindrome in Chinese. Once you can do that, you have arrived at total fluency…

        Did you study Japanese in Japan?

        -mox
Re: Improving a palindrome script...
by ikegami (Patriarch) on Oct 24, 2006 at 18:56 UTC

    Your code claims 'abc' is a palindrome.

    $test = $palindrome is an assignment. Wrong!
    $test == $palindrome is a numerical comparison. Still wrong!
    $test eq $palindrome is a string comparison. Good.
    lc($test) eq lc($palindrome) is a case-insensitive string comparison. Bingo!

    Perl's operators are documented in perlop.

Re: Improving a palindrome script...
by liverpole (Monsignor) on Oct 24, 2006 at 18:57 UTC
    Hi chinamox,

    I would not call those major challenges ...

    To test whether a string $str is 4 or more characters:

    if (length($str) >= 4) { # ... }

    To convert a string $str to lowercase (without "resorting to a regex"):

    my $lower = lc $str;

    Is that what you need?


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

      Thanks for those two little chunks of code! I am still quite new to Perl so these arn't really known to me yet. This is also why regexs still give me the willys!

      -mox
        Perl's functions are listed in perlfunc. They are grouped in categories, so you should have been able to find your answers very fast.
Re: Improving a palindrome script...
by skx (Parson) on Oct 24, 2006 at 21:41 UTC

    This is an interesting problem, even though it seems a little homework-like.

    Here is my solution.

    #!/usr/bin/perl -w # # Look for palindromes in a file. # # Usage: perl pal.pl file1 [file2] .. [fileN] # use strict; use warnings; # # Read the file. # while( <> ) { my $word = $_; # remove newline. chomp( $word ); # skip short words next if ( length( $word ) < 4 ); # reversal. my $text = reverse $word; # test + print print "Word: $word + $text\n" if ( lc( $word ) eq lc( $text ) ); }

    I see some output such as:

    skx@desktop:~$ perl pal.pl /usr/share/dict/words Word: Anna + annA .. Word: Hannah + hannaH .. Word: redder + redder Word: refer + refer
    Steve
    --
Re: Improving a palindrome script...
by driver8 (Scribe) on Oct 25, 2006 at 02:09 UTC
    Do what ikegami said and also throw in $palindrome =~ s/[^a-zA-Z]//g; in order to deal with things like danish custard.

    -driver8
      Be aware that such an action would also ignore accented letters. You might want to use s/\w+//g, s/[[:word:]]+//g or s/\p{IsWord}+//g, depending whether locale and/or unicode is in effect.