http://www.perlmonks.org?node_id=82812


in reply to Perl Golf Proposal

At a couple of people's suggestion, I'll post my solution. First, this problem arose because of large file collections posted on certain, ahem, alt.binaries newgroups. If you have a large number of files in a particular series, it can be rather cumbersome to cull through the directory and find the missing files, so I developed the following program to solve my problem.
It's probably a perlmonks sin to use Perl for such nefarious purposes, but I tried it in a couple of other languages and nothing gave me the ease of string checking against numeric values that Perl does, so of necessity was born another Perl convert.
What I meant by numeric or stringwise entry is that when the program asks for the search start and end, it should accept 0000 or 0, and for the end of the search range, should accept 0050 or 50. (The files tend to be named with leading zeros)
Anyway, here's the code, complete with my simplistic comments:

#!/usr/bin/perl -w empty.pl # Stan Harle # stan@harle.net # use strict; # Identify variables in advance (good practice!) my ($location, $L, $el, $el2, @srtlist, @filelist, $filcheck); my ($i, $p, $pre, $post, $strt, $ensr, $srtval, @filenames, $filenames +); my ($strt1, $ensr1); # Input the test directory into variable $location STARTING: print"Input the test directory\n"; chomp($location = <STDIN>); # Change directories to target directory chdir $location || muckup(); # Read file list into directory variable @filelist opendir (DIR, "$location"); @filelist = grep(!/^\.\.?$/, readdir (DIR)); closedir (DIR); @srtlist = sort @filelist; # Sort the values in the directory list array # Enter starting number for search print"What number do you want to start from\?"; chomp($strt = <STDIN>); $strt1 = $strt; # Enter Ending number for sequence of sort print"What number do you want to end at\?"; chomp($ensr = <STDIN>); $ensr1 = $ensr; # Loop to fill array with 1s to block out unneeded values for ($p = 0; $p <= $strt; $p++) { $filenames[$p] = 1; } # Loop to fill array with found and missing filenames for ($p = $strt; $p <= $ensr; $p++) { # This prevents an uninitialized place in case of no find $filenames[$p] = 0; foreach (@srtlist) { if ((/$strt1/) || ( (/$p(?![0-9])/) && (substr($',0,1) !~/ +[0-9]/) && (substr($`,-1,1)!~/[0-9]/)) ) { $filenames[$p] = 1; $pre = $`; $post = $'; } } $strt1++; } # Reinitialize $p and $i $p=0; $i=0; # Print out names of missing files foreach (@filenames) { if ($_ eq 0) { print "$pre$p$post\n"; $i++; # $i is just a checker for no missing files, +does nothing else } $p++; } print "\nNo Missing Files\!\n" if ($i eq 0); # Check for no mi +ssing files # Subroutine in case of user typos sub muckup { print"$location doesn't work.\n\n Did you mistype\?\n\n"; goto STARTING; }
which gave rise to the following solution:
This program is run with the start line
perl findit.pl /e/test 0000 0050

my($L,$b,$d)=@ARGV;opendir(DIR,"$L");@s=grep(!/^\.\.?$/,readdir(DIR)); +closedir(DIR);$b1=$b;for($p=$b;$p<=$d;$p++){$i=0;foreach(@s){$_=$s;if +((/$b1/)||((/$p(?![0-9])/)&&(substr($',0,1)!~/[0-9]/)&&(substr($`,-1, +1)!~/[0-9]/))){$i =1;}}print"$p\n"if($i eq 0);$b1++;}

271 characters.
While working out the golf solution I figured out that sorting the array isn't necessary, and neither is the change to the target directory, which gives even beginners reason to golf. :)

I apologize for not defining the parameters and exact nature of the problem more exactly, and I'll try to do better next time.

sharle