sharksfan98 sharksfan98 - 28 days ago 9
Perl Question

How to search for a six-letter word with letters in alphabetical order

I recently created a Perl script that searches for words that begin with D and and E with this code:

$infile = 'words.txt';
open(IN, $infile);
$count = 0;
while ($word = <IN>) {
chomp($word);
if ($word =~ /^d\w*e$/i) {
print "$word\n";
$count++;
}
}
print "$count\n";


I recently decided to fork the code and create a script that searches for a word that is six letters and letters in the word are in alphabetic (A to Z) order. Instead of using words.txt, I plan to use the Unix standard dictionary located at usr/share/dict/words. How can I accomplish this by modifying this code?

Answer Source

It looks like what you really need is an algorithm for checking whether the letters in a given word are in alphabetic sequence. There are several ways, but this subroutine works by splitting the word into a list of its constituent characters, sorting that list and recombining it. If the result matches the original word then that word was already sorted.

use strict;
use warnings;

use feature 'fc';

for (qw/ a ab ba cab alt effort toffee /) {
  print "$_\n" if in_alpha_order($_);
}

sub in_alpha_order {
  my $word = fc(shift);
  my $new = join '', sort $word =~ /./g;
  return $new eq $word;
}

output

a
ab
alt
effort

If you really wanted to do this in a regular expression, you could build an alternation like

a(?=[a-z]) | b(?=[b-z]) | c(?=[c-z]) ...

Here is a program that works that way. Its output is identical to that of the one above.

use strict;
use warnings;

my $regex = join '|', map "${_}(?=[$_-z])", 'a'..'z';
$regex = qr/^(?:$regex)*.$/i;

for (qw/ a ab ba cab alt effort toffee /) {
  print "$_\n" if $_ =~ $regex;
}