perl problems: problem one
And now for something completely different. I mentioned recently that I cut back my online hosting to one provider from two. This leaves me with some discretionary funds so I thought this would be fun.
Something new. This will be the inaugural entry. This is meant to promote and encourage perl usage for problem solving.
The problem while typical of a perl problem, is not intended to be tough, just diverting. When creating the regex if your code uses such, Regex Coach may assist you.
Perl Problem Number One:
Description of problem:
For a file named perl_problem_one read data in and
for every line that contains a valid part, output line plus part number to perl_solution_one file
output complete line like this with | delimiter between input line, and valid parts number.
T9476-467 063 SEAL D=18X3 | T9476-467 063
if no valid part number output line plus N/A
TAPPET,CLEANING ROD, #8867860 | N/A
close file and print "perl problem one solved" to stdout.
part is defined as a string starting with an alpha character and ten subsequent numbers. May contain spaces or dashes, output must be munged to look like:
alphaNNNN-NNN NNN
(that is a an alpha character plus four numbers then a dash and three numbers and then a space then three numbers.
Here is the data for the perl_problem_file:
Data:
J9476-467 063 SEAL D=18X3
Q9476-467 066 SEAL D=65X2.5
H9476-467 170 SEAL D-35X2.5
O9476-703 891 SEAL D=45
TAPPET,CLEANING ROD, #8867860
SEAL,FOR 8867864 866 868 870
T7048-031-801NOZZLE
NOZZLE,WVO 2.0 MM,FOR #8867860
T7048-031-802 4.0MM WVO NOZ
T9515-006-803NOZZLE,WVO,2.2MM
E9515014013PINTLE,2.2MM
C9515 006 801NOZZLE,WVO,4.0MM
V9515 014 011PINTLE,4.0MM
Your program when run should produce output like this to a perl_solution_one file:
Desired Output:
J9476-467 063 SEAL D=18X3 | J9476-467 063
Q9476-467 066 SEAL D=65X2.5 | Q9476-467 066
H9476-467 170 SEAL D-35X2.5 | H9476-467 170
O9476-703 891 SEAL D=45 | O9476-703 891
TAPPET,CLEANING ROD, #8867860 | N/A
SEAL,FOR 8867864 866 868 870 | N/A
T7048-031-801NOZZLE | T7048-031 801
NOZZLE,WVO 2.0 MM,FOR #8867860 | N/A
T7048-031-802 4.0MM WVO NOZ | T7048-031 802
T9515-006-803NOZZLE,WVO,2.2MM | T9515-006 803
E9515014013PINTLE,2.2MM | E9515-014 013
C9515 006 801NOZZLE,WVO,4.0MM | C9515-006 801
V9515 014 011PINTLE,4.0MM | V9515-014 011
Terms of contest entry:
All entries must be valid perl code, no pseudo code, and no other languages are eligible.
All entries remain property of submitter. Winner grants permission to kennethhunt.com to publish, comment, archive and redistribute the winning entry.
Winner grants permission to use his name, or nomme de plume in conjunction with describing the perl problems contest.Prize will be awarded to first entrant that posts code that outputs the sample correct code above, and produces similar results when fed a similar input file.
Data must be processed, no read file, the just printing result I gave is acceptable.First is defined as the earliest comment submitted below. Results is defined as producing similar output when fed data formatted in the same way.
If no winning entry is received by Midnight January 31st 2004, this contest is closed, and no prize shall be awarded for this problem.
Winner will receive on meeting the above conditions a cash equivalent prize valued at $50 US.*
*Non-US residents may enter but prize will be awarded with transaction costs subtracted for transferring prize monies to winner.
The winner may choose to receive an equivalent gift certificate for $50 US from his choice of online store.
If gift certificate is chosen, such store must offer material goodss for physical delivery.
0 TrackBacks
Listed below are links to blogs that reference this entry: perl problems: problem one.
TrackBack URL for this entry: http://kennethhunt.com/mt/mt-tb.cgi/965
The final entry that qualified is as follows:
#!/usr/local/bin/perl
$inputfile='perl_problem_file';
$outputfile='perl_solution_one';
open (FILE, "$inputfile") || die "Can't open file!\n";
@records = <FILE>;
close (FILE);
open (APPENDFILE, ">>$outputfile");
foreach $line (@records) {
chop ($line);
print APPENDFILE "$line | ";
$line =~ s/ //g;
$line =~ s/-//g;
if ($line =~ /[a-zA-Z]{1}\d{10}/) {
while ($line !~ /^[a-zA-Z]{1}\d{10}/) {
$line =~ s/.{1}//;
}
@array=split(//,$line);
print APPENDFILE @array[0].@array[1].@array[2].@array[3].@array[4]."-".@array[5].@array[6].@array[7]." ".@array[8].@array[9].@array[10]."\n";
} else {
print APPENDFILE "N/A\n";
}
}
close (APPENDFILE);
print "perl problem one solved\n";
I received my prize this morning. Thanks again.
You are correct. The samples all happened to have the part at the beginning, I spent to much time on the legalese and made that mistake with the filenames and not varying the data enough.
Assuming one valid part in a description is acceptable. Reply here when you get the gift certificate.
Fixed.
Your sample set implied that the string would always be at the beginning. If you don't make that assumption you run into possible conflicts. Take this possible line as an example:
QXJ9476467063Q9476467066
Do you assume the first matching substring is the part number? Or the last?
My code now assumes the first.
Note this code will not work completely with the following sample:
J9476-467 063 SEAL D=18X3
Q9476-467 066 SEAL D=65X2.5
H9476-467 170 SEAL D-35X2.5
O9476-703 891 SEAL D=45
TAPPET,CLEANING ROD, #8867860
SEAL,FOR 8867864 866 868 870
T7048-031-801NOZZLE
NOZZLE,WVO 2.0 MM,FOR #8867860
T7048-031-802 4.0MM WVO NOZ
T9515-006-803NOZZLE,WVO,2.2MM
E9515014013PINTLE,2.2MM
C9515 006 801NOZZLE,WVO,4.0MM
V9515 014 011PINTLE,4.0MM
D9709-008 185 SEAL
6T6277-220 003 SEAL, COP
9S0328-041 021 SPACER
1R6587-020 008 ROD
It fails to pull out:
T6277-220 003
S0328-041 021
R6587-020 008
Returning N/A instead for these lines which according to the definition of the part number:
"part is defined as a string starting with an alpha character and ten subsequent numbers. May contain spaces or dashes [...]"
Should be recognized as valid.
You can correct your entry if you wish.
That should read:
http://www.pjdoland.com/revolution/perl-one.pl.txt
Good eye.
Correction made to my file, and posted in it's completed state at
http://www.pjdoland.com/revolution/perl-one.pl.txt:
Nice work PJ, but the output line should have been
print APPENDFILE @array[0].@array[1].@array[2].@array[3].@array[4]."-".@array[5].@array[6].@array[7]." ".@array[8].@array[9].@array[10]."\n";
for the correct output as per the instructions.
-KHD
Correction, I used both naming conventions while describing this problem. perl_problem_one and perl_problem_file were both valid input filenames. oops. :)
One gotcha. PJ looks for perl_problem_file in his code. I specified perl_problem_one. Based on the results when I changed the dataset it appears robust enough to qualify. Good work. Look for a new problem in January.
I actually can't find your email address on your site, so I just posted the file here:
http://www.pjdoland.com/revolution/perl-one.pl.txt
Thanks for the comment PJ. I will check my email tonight.
The comments system butchered my code, as the less than and greater than signs didn't render right.
I'm emailing you the code.
#!/usr/local/bin/perl
$inputfile='perl_problem_file';
$outputfile='perl_solution_one';
open (FILE, "$inputfile") || die "Can't open file!\n";
@records = ;
close (FILE);
open (APPENDFILE, ">>$outputfile");
foreach $line (@records) {
chop ($line);
print APPENDFILE "$line | ";
$line =~ s/ //g;
$line =~ s/-//g;
if ($line =~ /^[a-zA-Z]{1}\d{10}/) {
@array=split(//,$line);
print APPENDFILE @array[0].@array[1].@array[2].@array[3]."-".@array[4].@array[5].@array[6]." ".@array[7].@array[8].@array[9]."\n";
} else {
print APPENDFILE "N/A\n";
}
}
close (APPENDFILE);
print "perl problem one solved\n";