Home: Fun With Perl: Perl Golf:
String Replacement Golf



fashimpaur
User / Moderator

Feb 14, 2002, 7:16 AM


Views: 89386
String Replacement Golf

Okay. Since there isn't much happening today at the forum, it's time for some more
fun. I recently ran into a problem where the version of Perl running on a web server
was 5.002. In that version, the substr overload of the type
substr EXPR,OFFSET,LEN,REPLACEMENT was not defined yet. The code that was
being written required a string of substantial length to have a portion of it replaced
with a new value. I wrote a function overload myself for substr to enable this to
be executed in the code.

The Task

Create a method mysubstr to perform the same task as explained above in as
few characters as possible. It must be reusable for any inputs (no hard coding).
The substring replacement is going to be assumed to be placed within the bounds
of the original expression. There is no need to check to see if you will exceed the
length of the original expression. We just don't care.

The Rules

1). The method need only work for any positive OFFSET or LEN (You don't have to work
backwards).


2). The method returns the modified string.

Common Input Parameters: (So we all start fair):

$a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; # EXPR
$b = 15; # OFFSET
$c = "Perl_Is_Fun"; # REPLACEMENT
$d = length $c; # LEN

# the method would be called as #
$e = mysubstr($a, $b, $d, $c);
# test result #
print $e;
# (expecting: abcdefghijklmnoPerl_Is_FunABCDEFGHIJKLMNOPQRSTUVWXYZ) #

You are given the following characters for free:
sub mysubstr{}

All characters between the curly braces are counted.
All manipulation must be done within the curly braces. No cheating.

My answer (in it's worst looking form) took 60 characters.
Someone out there can do better. I am waiting to see your answers.

[spoiler]

sub mysubstr{$s=shift,$s=~s/^(.{$_[0]})(.{$_[1]})(.*)/\1$_[2]\3/,return$s};

[/spoiler]

Good Luck.

Dennis

$a="c323745335d3221214b364d545".
"a362532582521254c3640504c3729".
"2f493759214b3635554c3040606a0",
print unpack"u*",pack "h*",$a,"\n\n";


Paul
Enthusiast

Feb 14, 2002, 8:45 AM


Views: 89382
Re: [fashimpaur] String Replacement Golf

You have:

(.{$_[1]})

....but $_[1] is Perl_Is_Fun isn't it?


(This post was edited by RedRum on Feb 14, 2002, 8:46 AM)


Paul
Enthusiast

Feb 14, 2002, 8:48 AM


Views: 89380
Re: [fashimpaur] String Replacement Golf

I managed to beat you by about 6 characters:


Code
sub mysubstr{$s=shift,$s=~s/^(.{$_[0]})(.{$_[1]})/\1$_[2]/,return$s};



freddo
User

Feb 14, 2002, 9:30 AM


Views: 89375
Re: [fashimpaur] String Replacement Golf

Hi,

Got this for now (43):
[spoiler]sub mysubstr{shift;/(.{$_[0]}).{$_[2]}(.*)/;"$1$_[1]$2";}[/spoiler]

freddo
;---


freddo
User

Feb 14, 2002, 9:36 AM


Views: 89374
Re: [freddo] String Replacement Golf

damn, 42, if i remove the last ";" where did my head go?
;---


fashimpaur
User / Moderator

Feb 14, 2002, 12:40 PM


Views: 89367
Re: [RedRum] String Replacement Golf

RedRum,

$s was $_[0] and was shift(ed) in.
$_[0] is now OFFSET,
$_[1] is now LEN,
$_[2] is now REPLACEMENT.

I am. Therefore I think?
Dennis

$a="c323745335d3221214b364d545".
"a362532582521254c3640504c3729".
"2f493759214b3635554c3040606a0",
print unpack"u*",pack "h*",$a,"\n\n";


Paul
Enthusiast

Feb 14, 2002, 12:58 PM


Views: 89365
Re: [fashimpaur] String Replacement Golf

[perl]
sub {
#-----------------------------

print "I bet you can't do this\n\n";

@_=qw/1 2 3 4 5/;

print, for @_;

}
[/perl]


fashimpaur
User / Moderator

Feb 14, 2002, 1:21 PM


Views: 89364
Re: [RedRum] String Replacement Golf

RedRum,

Improving on freddo I get 39!

[spoiler]

sub mysubstr{$_[0]=~/(.{$_[1]}).{$_[2]}/;$1.$_[3].$'}

[/spoiler]

I also see your comment about what was in $_[2] was for freddo. Sorry.

Dennis

$a="c323745335d3221214b364d545".
"a362532582521254c3640504c3729".
"2f493759214b3635554c3040606a0",
print unpack"u*",pack "h*",$a,"\n\n";


fashimpaur
User / Moderator

Feb 14, 2002, 1:27 PM


Views: 89363
Re: [RedRum] String Replacement Golf

How do you call that? &();? No. I give. You win!
Dennis

$a="c323745335d3221214b364d545".
"a362532582521254c3640504c3729".
"2f493759214b3635554c3040606a0",
print unpack"u*",pack "h*",$a,"\n\n";


Paul
Enthusiast

Feb 14, 2002, 2:11 PM


Views: 89362
Re: [fashimpaur] String Replacement Golf

Sorry that was unrelated to the thread.

I was trying to point out the new tag available to colorize perl code :)

[perl] some code here [/perl]


freddo
User

Feb 14, 2002, 3:23 PM


Views: 89359
Re: [fashimpaur] String Replacement Golf

Hi Fashimpaur,

we're both wrong... Crazy
first, i just saw i copy/pasted the wrong mysubstr from the perl debugger, it should have been:[spoiler]sub mysubstr{$_=shift;/(.{$_[0]}).{$_[2]}(.*)/;"$1$_[1]$2"}[/spoiler](which makes it 46 bytes)... and secondly you inverted $_[2] & $_[3] Wink

so..... who shorten it next?
freddo

updated: finally pasted the good sub, damn.
;---

(This post was edited by freddo on Feb 14, 2002, 3:31 PM)


Paul
Enthusiast

Feb 15, 2002, 1:57 AM


Views: 89353
Re: [freddo] String Replacement Golf

Can I ask what the point of the spoiler tag is?

I really don't get it :)


freddo
User

Feb 15, 2002, 3:49 AM


Views: 89350
Re: [RedRum] String Replacement Golf

Hi Redrum,

Well, i think it's useful if some one wants to play, he doesnt see the others solutions unless he wishes to. So the quiz isnt "spoilt", he can still enjoy searching his own answer.

Freddo
;---


Paul
Enthusiast

Feb 15, 2002, 3:50 AM


Views: 89349
Re: [freddo] String Replacement Golf

Ahhh now I see :)


fashimpaur
User / Moderator

Feb 15, 2002, 4:37 AM


Views: 89346
Re: [freddo] String Replacement Golf

freddo,

Sorry, my friend, but you are mistaken. It is you that has been
inverting $_[2] and $_[3]. If you see in the original post, the
method is called mysubstr($a, $b, $d, $c) not mysubstr($a, $b, $c, $d).
If I invert my input parameters like that, and swap the variables
that you say are swapped, my method is still 39 characters and produces the
desired output. Unsure

Dennis
Dennis

$a="c323745335d3221214b364d545".
"a362532582521254c3640504c3729".
"2f493759214b3635554c3040606a0",
print unpack"u*",pack "h*",$a,"\n\n";


Paul
Enthusiast

Feb 15, 2002, 5:11 AM


Views: 89344
Re: [fashimpaur] String Replacement Golf

I think you have it wrong.....

$a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; # EXPR
$b = 15; # OFFSET
$c = "Perl_Is_Fun"; # REPLACEMENT
$d = length $c; # LEN

sub mysubstr{$s=shift,$s=~s/^(.{$_[0]})(.{$_[1]})(.*)/\1$_[2]\3/,return$s};


If $s is shift then $_[0] is 15 .....thats fine!

However $_[1] is Perl_Is_Fun which cannot go inside curly braces.

Whichever way you do it either $_[0] or $_[1] will be letters which is invalid.


(This post was edited by RedRum on Feb 15, 2002, 5:13 AM)


freddo
User

Feb 15, 2002, 5:56 AM


Views: 89340
Re: [fashimpaur] String Replacement Golf

Ooooops,

I'm sorry, you're absolutely right, the fact is i just copied the lines defining the variables and used a, b, c and d in that order... silly me.

btw, i came trying it this way, for now it's quite awful (59 and using a,b,c,d) and i'm just playing with it, if you're tempted give it a look:[spoiler]sub mysubstr{@x=split//,$_[0];@x[0..$_[1]-1],$_[2],@x[$_[1]+$_[3]..$#x]}[/spoiler]

Sorry again for saying you were wrong,
Freddo
;---


fashimpaur
User / Moderator

Feb 15, 2002, 6:07 AM


Views: 89339
Re: [RedRum] String Replacement Golf

My last solution was:

sub mysubstr{$_[0]=~/(.{$_[1]}).{$_[2]}/;$1.$_[3].$'}

the method is:

mysubstr(EXPR, OFFSET, LEN, REPLACEMENT);

Therefore the code reads:

Find in $_[0] a match of $_[1] number of any type of character, followed
by $_[2] number of any type of character. (The searching of the string
will stop as soon as the first match is found.)

Then concatenate the first parenthesized match and the replacement
($_[3]) and anything that followed the whole match and put the result
in $_. Since mysubstr is called as:

$e = mysubstr($a, $b, $d, $c), the correct result is printed.

Did I miss something here? My whole code test is:


Code
 $a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";  
# EXPR
$b = 15;
# OFFSET
$c = "Perl_Is_Fun";
# REPLACEMENT
$d = length $c;
# LEN
# the method would be called as #
$e = mysubstr($a, $b, $d, $c);
# test result #
print $e;
# (expecting: abcdefghijklmnoPerl_Is_FunABCDEFGHIJKLMNOPQRSTUVWXYZ) #
print "\n\n";
print length q!$_[0]=~/(.{$_[1]}).{$_[2]}/;$1.$_[3].$'!;
sub mysubstr{$_[0]=~/(.{$_[1]}).{$_[2]}/;$1.$_[3].$'}


Let me know if there is anything that does not conform to the
rules. I thought I did it right.
Dennis

$a="c323745335d3221214b364d545".
"a362532582521254c3640504c3729".
"2f493759214b3635554c3040606a0",
print unpack"u*",pack "h*",$a,"\n\n";


(This post was edited by fashimpaur on Feb 15, 2002, 6:16 AM)


fashimpaur
User / Moderator

Feb 15, 2002, 6:09 AM


Views: 89338
Re: [freddo] String Replacement Golf

No problem. After all, this is only supposed to be for fun. Sly
Dennis

$a="c323745335d3221214b364d545".
"a362532582521254c3640504c3729".
"2f493759214b3635554c3040606a0",
print unpack"u*",pack "h*",$a,"\n\n";