Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: P2P Golf: MoleSter

by dragonchild (Archbishop)
on Dec 16, 2004 at 14:04 UTC ( [id://415348]=note: print w/replies, xml ) Need Help??


in reply to P2P Golf: MoleSter

It'd be nice to know how to test this w/o requiring another active P2P peer. That said, I found 10 characters, simply from syntax. If we didn't mind it being like 30 lines long, we could take advantage of newlines for another 15ish characters.
$p=shift;$a=a(shift);i(shift);socket S,2,1,6;bind S,$a;listen S,5;undef$/;while(@ARGV&&($_="$p $a f".shift)||accept(C,S)&&($_=<C>)&& +close C){m!^(.*?) (.*?) ([e-i])([^/]*)/!s&&$1 eq$p&&&$3($2,$4,$')}sub e{open F,'>',$_[1];print F $_[2];close F}sub f{t($_,@_)for keys%k}sub g{open(F,'<',$_[1])&& t($_[0],$a,"e$_[1]",<F>);close F}sub h{t($_[0],$_,'i')for keys%k}sub i{$k{$_[0]}=1}sub a{$_[0]=~/:/;pack'CxnC4x8',2,$',split'\.',$`}sub t{socket X,2,1,6;$w=shift;if(connect X,a($w)){print X "$p $_[0] $_[1]/$_[2]";close X}else{undef$k{$p}}}

Update: This is what I just submitted back to the author. I think it ends up being 516 characters over 8 lines.

$/=$_;$(=shift;$a=shift;i(shift);socket S,2,1,6;bind S,a($a);listen S,5;while(@ARGV&&($_="$( $a f".shift)||accept(C,S)&&($_=<C>)&&close C){m!^(.*?) (.*?) ([e-i])([^/]*)/!s&&$(eq$1&&&$3($2,$4,$')}sub f{t($_, +@_)for keys%k}sub a{pop=~/:/;pack'CxnC4x8',2,$',split'\.',$`}sub i{$k{$_[0]}= +1}sub g{open(F,"<$_[1]")&& t($_[0],$a,"e$_[1]",<F>);close F}sub h{t($_[0],$_ +,'i')for keys%k}sub t{socket X,2,1,6;if(connect X,a($w=shift)){print X "$( $_[0] $_[1]/$_[2]";close X}else{undef$k{$w}}}sub e{open F,">$_[1]";print F $_[2];close F}

Being right, does not endow the right to be rude; politeness costs nothing.
Being unknowing, is not the same as being stupid.
Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Replies are listed 'Best First'.
Re: P2P Golf: MoleSter
by jonadab (Parson) on Dec 17, 2004 at 04:16 UTC

    You did better than I did (_especially_ with optimizing sub a, and with getting rid of the Socket constants, which I knew was possible but didn't do), although you did miss a couple of opportunities...

    • As someone else also noted, undef$/, while it saves one stroke over the original, is still suboptimal. I have $/=$3. A related situation occurs later with undef$k{$p}, only there $3 might be defined, so I have $k{$p}=$7 in that case. $7 will always be undef in molester. Update: your updated version does this in the first of the two cases.
    • open F,'>',$_[1] is slightly suboptimal. I have open F,">$_[1]", saving one stroke. I saved another stroke doing the same thing when it's opened for reading. Update: your updated version does this too.
    • Because sub a is declared before sub t, you can dispense with the parens when t calls a, saving two characters: (connect X,a$w) Update: your updated version does even better than this.
    • My /. post doesn't _demonstrate_ this, but it mentions it: converting the if/else isn't as fruitful as I'd hoped, due to the need to use and after the print (for precedence reasons), but it does shave off a couple of strokes. Update: I believe this is still good for a couple of strokes.
    • another update: I think we can shave one more stroke by using a statement modifier in sub g. This will cause F to be closed whether it's successfully opened or not, but that should be okay I _think_.
    • Yet Another Update: But I lost that character again fixing what I think is a bug in your regex optimization, having to do with the slashes that separate commands.

    We also both missed the argumentless-close trick that someone else pointed out, although I would have to test that one to be sure it doesn't close the socket also (or that doing so doesn't change the operation of the script). Can someone confirm which close statements need their arguments and, for that matter, whether it's possible to eliminate any of the close statements altogether without breaking something?

    So I threw out my version and worked from yours update: again, and this is what I now have, weighing in at 508 bytes not counting line breaks (522 bytes with a full ASCII CRLF ending every line but the last, or 515 with Unix-style one-character newlines):

    $/=$_;$(=shift;$a=shift;i(shift);socket S,2,1,6;bind S,a($a);listen S,5;while(@ARGV&&($_="$( $a f".shift)||accept(C,S)&&($_=<C>)&&close C){m!^(.*?) (.*?) ([e-i])([^/]*)./!s&&$(eq$1&&&$3($2,$4,$')}sub f{t($_ +,@_)for keys%k}sub a{pop=~/:/;pack'CxnC4x8',2,$',split'\.',$`}sub i{$k{$_[0]}= +1}sub g{t($_[0],$a,"e$_[1]",<F>)if open F,"<$_[1]";close F}sub h{t($_[0],$_, +'i')for keys%k}sub t{socket X,2,1,6;(connect X,a($w=shift))?print X"$( $_[0] $_[1]/$_[2]"and close X:$k{$w}=$7}sub e{open F,">$_[1]";print F $_[2];close F}

    Note that this code is completely, utterly untested.


    "In adjectives, with the addition of inflectional endings, a changeable long vowel (Qamets or Tsere) in an open, propretonic syllable will reduce to Vocal Shewa. This type of change occurs when the open, pretonic syllable of the masculine singular adjective becomes propretonic with the addition of inflectional endings."  — Pratico & Van Pelt, BBHG, p68
      I got a reply from the author and worked a "little" on it this morning. I'm down to 470 characters over 6 lines. There's a few bugs and several security holes fixed. Fixing them cost a few bytes, but I think it's worth it, overall. I mean, what use is showing Python we can beat them in program size if the program sucks? We have to show them we can write secure network software in 6 lines or less. *grins*

      The author is working on revamping the while() loop and moving to use read() instead of <> for the socket. But, I don't have that version, so I'll work with what I have.

      sub f{for$w(keys%k){&t}}$/=$_;($,,$w=$a,%k)=splice@ARGV,0,3;socket S,2 +,1,6;bind S,&a;sub i{$k{$w}=1}sub a{$w=~/:/;pack'CxnC4x8',2,$',split'\.',$`}sub +t{socket X,2,1,6;if(connect X,a){print X "$, $_[0] $_[1]/$_[2]";close}else{dele +te$k{$w}}} listen S,5;while(@ARGV&&($_="$, $a f".shift)||accept(C,S)&&($_=<C>)&&c +lose){ m!(\S*) ([e-i])([^/]*)/!s&&$,eq$`&&&$2($w=$1,$3,$')}sub e{open F,'>',$ +3;print F $';close}sub g{open(F,'<',$3)&&t$a,"e$3", <F>;close F}sub h{t$_,i for +keys%k}

      This code is sooo completely untested. :-) The readable version ...

      Update: After jonadab's suggestions and some reorganization, we save 11 characters (down to 459 over 6 lines):

      sub f{for$w(keys%k){&t}}$/=$_;($,,$w=$a,%k)=splice@ARGV,0,3;socket S,2 +,1,6;bind S,&a;sub i{$k{$w}=1}sub a{$w=~/:/;pack'CxnC4x8',2,$',split'\.',$`}sub +t{socket X,2,1,6;connect(X,a)?print(X "$, $_[0] $_[1]/$_[2]")&&close:delete$k{$ +w}}listen S,5;while(@ARGV&&($_="$, $a f".shift)||accept(C,S)&&($_=<C>)&&close){s +ub h{t$_,i for keys%k}m!(\S*) ([e-i])([^/]*)/!s&&$,eq$`&&&$2($w=$1,$3,$')}sub e{o +pen F,'>',$3;print F $';close}sub g{open(F,'<',$3)&&t$a,"e$3",<F>;close F} }

      Yes, there's a subroutine definition in the while-loop. "perl -MO=Deparse" tells me it's ok.

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        Wow, there's clearly an evil genius at work here. The splice is an interesting conversion. The thing you're doing calling i in sub h is slightly confusing, but I understand what you're doing with the regex in the while loop now, which I somehow missed last night. (Oh, I see, it was front-anchored in last night's version. That must be one of the bug fixes. But, won't $` contain the separating slash now? I'm still confused there. You've golfed it beyond my ability to follow it.)

        • You've still got the verbose if/else blocks in sub t. Converting to the trinary operator saves, if my calculations are correct, three strokes if you have to parenthesize the middle part, five if you don't. Am I missing something?
        • You've gone back to the three-argument open; is that one of the bug fixes you mentioned? I thought it was semantically the same... and if not, I want to understand the difference for reasons that have nothing to do with obfuscation, golf, or P2P.
        • I assume the delete is a bugfix, to purge dead peers from %k entirely. Makes sense.
        • The space after the comma in sub g, what's the reasoning behind that?
Re^2: P2P Golf: MoleSter
by bgreenlee (Friar) on Dec 16, 2004 at 18:32 UTC

    You should be able to get rid of at least 4 more characters by getting rid of the " F" after the two "close F"'s. Without an argument, close will close the currently selected filehandle.

    The above is actually 7 lines if you get every line as close to 80 chars as possible.

    -b

      The above is actually 7 lines if you get every line as close to 80 chars as possible.

      True, but you gain characters by doing that. The reason for where the newlines are is to cut spaces from the final tally. You'll notice every newline is after a select, close, sub, or for. That's not coincedence. :-)

      Thanks for the tip on close().

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re^2: P2P Golf: MoleSter
by eric256 (Parson) on Dec 16, 2004 at 14:27 UTC

    The easiest way to test it is to run it twice, and have each instance run on a different port. Then they can communicate with each other.


    ___________
    Eric Hodges

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://415348]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-04-16 23:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found