[SPOILER] Re: 'Easy' Quiz #2005-2 (Perl... and Pascal)
David Jones <[email protected]> Sun, 06 Feb 2005 14:36:22 +0100
| Newsgroups | gmane.comp.lang.perl.qotw.discuss |
|---|---|
| Organization | Vaudeloges Communication |
| Message-ID | <FADFDWTRNNJ6HCPKVSMKFD07QL41JI.42061d56@topcat> |
Most of my efforts are similar to ones already posted.
Just to nitpick, however, note that nothing in the 'spec' said that:
(1) the string passed to the function must be non-empty; or
(2) the string cannot contain embedded new lines.
Concerning (2), and taking a submitted example at random:
sub lookahead {
my $s = shift;
$s =~ s/\.(?=.*\.)//g;
return $s;
}
Feed this with:
print lookahead( "a.b.\nc.d.\ne.f.");
and you will get:
ab.
cd.
ef.
instead of:
ab
cd
ef.
Of course, the fix here is easy (one character to add).
Anyway, for fun (?), since they're making me learn Pascal (at my age!),
and since people seem to be posting code in more and more languages,
I include a Pascal solution. First, the Perl translation:
sub undot_Pascal_style {
return '' unless my $str = shift; # Shut warnings up for empty strings
my $seen;
my $new_str = '';
for ( my $i = length ( $str ) - 1; $i >= 0; $i-- ) {
if ( substr ( $str, $i, 1 ) eq '.') {
if ( $seen ) { next; }
else { $seen++; }
}
$new_str = substr ( $str, $i, 1 ) . $new_str;
}
return $new_str;
}
Still Perl, same algortihm, but using chop (I've become fond of chop
recently :-) and replacing the ugly nested if/elses with an even uglier
single line:
sub undot2 {
return '' unless my $str = shift;
my $seen;
my $new_str = '';
while ( $str ) {
my $char = chop $str;
$char eq '.' and !$seen and $seen++ or next;
$new_str = $char . $new_str;
}
return $new_str;
}
I've wrapped the Pascal function in a program, in the unlikely event that
anyone should want to compile and test it :-).
I often wish that Perl allowed "$string[$i]" syntax, although of course that
would conflict with "$array[$i]" (will this change with Perl 6?)
program strip_dots;
function undot (str: string): string;
var
seen : boolean;
new_str : string;
i : integer;
begin
seen := false;
new_str := '';
for i := length(str) downto 1 do
begin;
if str[i] = '.' then
if seen then continue
else seen := true;
new_str := str[i] + new_str;
end;
undot := new_str;
end; { undot }
var
my_str : string;
begin
write('Enter a string: ');
readln(my_str);
writeln(undot(my_str));
end.
dave