Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

perl script

28 views
Skip to first unread message

Nathan Peterson

unread,
Dec 4, 2001, 8:43:21 PM12/4/01
to
I was messing around with perl today and I managed to write a 1 1/2 line
script to determine wether or not a siteswap pattern is valid. I was
wondering if there were any Perl geeks out there who'd like to take a
crack at this. I'm sure the code could be shrunk a little. Here's what
I came up with:

#!/usr/bin/perl
@s=split//,$ARGV[0];for($t=0;$t<@s;$t++){for($j=$t+1;$j<@s;$j++){$v+=!(($s[$t]+$
t-$s[$j]-$j)%@s);}}print$v?"invalid":"valid";


-Nathan

Alan Morgan

unread,
Dec 4, 2001, 10:53:32 PM12/4/01
to
In article <3C0D7BB9...@juggler.net>,

I did a little bit of tightening up but didn't change anything fundamental.

#!/usr/bin/perl
split//,$ARGV[0];for$t(0..@_-1){for$j($t+1..@_-1){$v+=!(($_[$t]+$t-$_[$j]-$j)%@_)
;}}print$v?"invalid":"valid";

It still doesn't handle throws higher than 9, however. Bummer.

Alan

Mañungo

unread,
Dec 5, 2001, 12:15:55 AM12/5/01
to

Alan Morgan wrote:
>
> I did a little bit of tightening up but didn't change anything fundamental.
>
> #!/usr/bin/perl
> split//,$ARGV[0];for$t(0..@_-1){for$j($t+1..@_-1){$v+=!(($_[$t]+$t-$_[$j]-$j)%@_)
> ;}}print$v?"invalid":"valid";

^^^^^^^^^^^^^^
Try:
print"in"x$v."valid";

>
> It still doesn't handle throws higher than 9, however. Bummer.
>
> Alan

Another form (shortest):

#!/usr/bin/perl
split//,pop;map{$k=pop@_;map{($k-$_)%$i||die"invalid"}@_}map{$_[$i]+=$i++}@_;print"valid";


Saludos!! Mannungo
---------------------------------------------------
Malabarista de oficio
Ingeniero en los ratos libres...
Malabarismo: http://www.malabarismo.cl

Nathan Peterson

unread,
Dec 5, 2001, 11:32:26 AM12/5/01
to
> Try:
> print"in"x$v."valid";


Ahh, I was wondering if there was a way to do that :-)


> Another form (shortest):
>
> #!/usr/bin/perl
> split//,pop;map{$k=pop@_;map{($k-$_)%$i||die"invalid"}@_}map{$_[$i]+=$i++}@_;print"valid";


great work!! I'm impressed :) It doesn't quite make the 1 liner
critera though since it's over 80 chars :-( It believe it should be:

Nathan Peterson

unread,
Dec 5, 2001, 11:48:11 AM12/5/01
to
Nathan Peterson wrote:

>> Try:
>> print"in"x$v."valid";
>
>
>
> Ahh, I was wondering if there was a way to do that :-)

Wait a minute. You're assuming that $v is going to equal 0 or 1.
Sometimes it's greater than 1. $v basically counts the number of
collisions. So for instance 63161321 has 3 collisions so the script
would output: "inininvalid"

-Nathan

William Gilliland

unread,
Dec 5, 2001, 3:47:28 PM12/5/01
to
: great work!! I'm impressed :) It doesn't quite make the 1 liner
: critera though since it's over 80 chars :-( It believe it should be:

If you're willing to accept uglier output you can get down to 78 characters.

#!/usr/bin/perl
split//,pop;map{$k=pop@_;map{($k-$_)%$i||die"n"}@_}map{$_[$i]+=$i++}@_;die"y";

Of course, lets add features :) If we use a b c... for 10 11 12... we can
accept throws higher than 9. Have to go back to 2 lines, might as well
prettify the output again...

#!/usr/bin/perl
split//,pop;map{$k=pop@_;map{($k-$_)%$i||die"invalid\n"}@_}map{if(/\D/)
{$_=-87+ord}$_[$i]+=$i++}@_;die"valid\n";

--
This message brought to you by Bill Gilliland, bi...@ucdavis.edu
(.sig as modified by Jeff Newmiller)

#! /usr/bin/perl
for(split q,,,q,x!$G.86x!#)256x!$'2W6x!#"256x!$G.8+xx:TK9S>-ExF++B&*3UxFT+,
.q,:(*3MxF++&&*3Ex:S/9V*-Exxxx,){if($i=6,/x/x){print"\n"}else{$x=-33+ord;
while($i--){if(1<<$i<=$x){print'#';$x-=2** $i}else{print' ';$#_;}}}}

Alan Mackenzie

unread,
Dec 5, 2001, 4:26:27 AM12/5/01
to
Alan Morgan <amo...@xenon.stanford.edu> wrote on 5 Dec 2001 03:53:32
GMT:

Heyisthereanychanceyouguyscouldyouknowlikeaddabitofwhitespace
formatthescriptsemireadablypossiblyevenadda....COMMENT..ortwo.Perl
isntAPLanditcertainlyshouldntlooklikeTECO.

> Alan

--
Alan Mackenzie (Munich, Germany)
Email: aa...@muuc.dee; to decode, wherever there is a repeated letter
(like "aa"), remove half of them (leaving, say, "a").

Dave Barnes

unread,
Dec 5, 2001, 5:24:13 PM12/5/01
to
Alan Mackenzi wrote:

> Heyisthereanychanceyouguyscouldyouknowlikeaddabitofwhitespace
> formatthescriptsemireadablypossiblyevenadda....COMMENT..ortwo.
> PerlisntAPLanditcertainlyshouldntlooklikeTECO.

Have you encountered the game of Perl Golf, Alan? It's explained on
http://www.sysarch.com/perl/golf/ Basically, the point is to solve a
problem in the fewest keystrokes. Comments and readability aren't really
compatible with that idea! Also, the more obfuscated the code is, the
better!

Dave

----== posted via www.jugglingdb.com ==----

Gunnar Andersson

unread,
Dec 6, 2001, 3:52:12 AM12/6/01
to

On Wed, 5 Dec 2001, Alan Mackenzie wrote:

> > #!/usr/bin/perl
> > split//,$ARGV[0];for$t(0..@_-1){for$j($t+1..@_-1){$v+=!(($_[$t]+$t-$_[$j]-$j)%@_)
> > ;}}print$v?"invalid":"valid";
>
> Heyisthereanychanceyouguyscouldyouknowlikeaddabitofwhitespace
> formatthescriptsemireadablypossiblyevenadda....COMMENT..ortwo.Perl
> isntAPLanditcertainlyshouldntlooklikeTECO.

Perl - the only language that looks the same before and after RSA
encryption.

/ Gunnar

Little Paul

unread,
Dec 6, 2001, 7:27:40 AM12/6/01
to

print$v?"in":"","valid";

works though... it might be 3 characters longer than

print"in"x$v."valid";

but it is 2 shorter than

print$v?"invalid":"valid";

Hmmm... Problem now being, I understand what the rest of the script
is doing, but not *why* the algorithm works, but then I don't really
know a lot about what makes a siteswap valid, so I'm at a bit of a
disadvantage, so I'll shut up now.

-Paul
www.lpbk.net/caption/ - See me, laugh, poke fun at me.

Steve Carter

unread,
Dec 6, 2001, 7:22:32 AM12/6/01
to
> #!/usr/bin/perl
>
split//,$ARGV[0];for$t(0..@_-1){for$j($t+1..@_-1){$v+=!(($_[$t]+$t-$_[$j]-$j
)%@_)
> ;}}print$v?"invalid":"valid";
>
> It still doesn't handle throws higher than 9, however. Bummer.
>

This one does. It's got a Pretty edition (output on stdout) and an ugly
edition (exit status 0 for valid;
non-zero for invalid) you give the site swap space-separated so you can have
./ss4.pl 11 9

#!/usr/bin/perl
@s=@ARGV;for($i=0;$i<@s;){$_|=$t[($s[$i]+$i++)%@s]++;}print$_?'n':'y';

#!/usr/bin/perl
@s=@ARGV;for($i=0;$i<@s;){$_|=$t[($s[$i]+$i++)%@s]++;}exit($_);

It creates an array @t that counts the landings at a particular position.
If the landings anywhere exceed 1 then the flag is set.
Another trick is to omit $i++ from the for statement and put ++ next to a $i
in the body of the loop, where you would have to
mention it anyway.


Little Paul

unread,
Dec 6, 2001, 8:50:21 AM12/6/01
to
Steve Carter wrote:

> This one does. It's got a Pretty edition (output on stdout) and an ugly
> edition (exit status 0 for valid;
> non-zero for invalid) you give the site swap space-separated so you can have

> ../ss4.pl 11 9


>
> #!/usr/bin/perl
> @s=@ARGV;for($i=0;$i<@s;){$_|=$t[($s[$i]+$i++)%@s]++;}print$_?'n':'y';
>
> #!/usr/bin/perl
> @s=@ARGV;for($i=0;$i<@s;){$_|=$t[($s[$i]+$i++)%@s]++;}exit($_);
>
> It creates an array @t that counts the landings at a particular position.
> If the landings anywhere exceed 1 then the flag is set.
> Another trick is to omit $i++ from the for statement and put ++ next to a $i
> in the body of the loop, where you would have to
> mention it anyway.

Or if you want to shave a further 5 characters off each, you've got

#!/usr/bin/perl
@s=@ARGV;for$i(0..$#s){$_|=$t[($s[$i]+$i)%@s]++;}print$_?'n':'y';

#!/usr/bin/perl
@s=@ARGV;for$i(0..$#s){$_|=$t[($s[$i]+$i)%@s]++;}exit($_);

Well, I think thats right... (It seems to work...)

-Paul
www.lpbk.net/caption/ - Am I capable of looking like a non-juggler?

Alan Mackenzie

unread,
Dec 6, 2001, 8:27:00 AM12/6/01
to
Dave Barnes <bar...@juggler.net.nospam> wrote on Wed, 5 Dec 2001
22:24:13 +0000 (UTC):
> Alan Mackenzi wrote:

>> Heyisthereanychanceyouguyscouldyouknowlikeaddabitofwhitespace
>> formatthescriptsemireadablypossiblyevenadda....COMMENT..ortwo.
>> PerlisntAPLanditcertainlyshouldntlooklikeTECO.

AIC

> Dave

--
Alan Mackenzie (Munich, Germany)
Email: aa...@muuc.dee; to decode, wherever there is a repeated letter

(like "aa") remove half of them (leaving, say, "a").

Steve Carter

unread,
Dec 6, 2001, 1:39:26 PM12/6/01
to
> Or if you want to shave a further 5 characters off each, you've got
>
> #!/usr/bin/perl
> @s=@ARGV;for$i(0..$#s){$_|=$t[($s[$i]+$i)%@s]++;}print$_?'n':'y';
>
> Well, I think thats right... (It seems to work...)

Yes, can't fault that, but I think it's in danger of becoming bloatware,
what with having three separate statements spread over 64 characters. I
think it's much clearer if written in a single clear statement of the
semantics of the problem. Like this:

#!/usr/bin/perl
print map(@t[($_+$i++)%@ARGV]++=~/1/,@ARGV)?'n':'y';

(53 chars)


Alan Morgan

unread,
Dec 6, 2001, 1:42:00 PM12/6/01
to
In article <9uno7n$30n7$1...@purple.gradwell.net>,

Little Paul <l...@juggler.net.nospam> wrote:
>Nathan Peterson wrote:
>> >> print"in"x$v."valid";
>> > Ahh, I was wondering if there was a way to do that :-)
>>
>> Wait a minute. You're assuming that $v is going to equal 0 or 1.
>> Sometimes it's greater than 1. $v basically counts the number of
>> collisions. So for instance 63161321 has 3 collisions so the script
>> would output: "inininvalid"
>
>print$v?"in":"","valid";

I was looking for this trick but couldn't find the right incantation. :-(

BTW - To the person who produced the 'map' version. Very nice. I spent
a little time trying to get that to work but I couldn't figure out how
to get the index of each item in the map call.

>Hmmm... Problem now being, I understand what the rest of the script
>is doing, but not *why* the algorithm works, but then I don't really
>know a lot about what makes a siteswap valid, so I'm at a bit of a
>disadvantage, so I'll shut up now.

Essentially, if two throws are made 'n' beats apart then the difference
between their heights can not be a multiple of the length of the pattern
plus n, or you will get a collision.

If this condition is met for all pairs of throws then you have a valid site
swap

Alan

Alan Morgan

unread,
Dec 6, 2001, 1:43:51 PM12/6/01
to
In article <Pine.GSO.4.31.011206...@my.nada.kth.se>,

Rumor has it that, in the spirit of the Internation Obfuscated C Code Competition,
there was an International Unobfuscated Perl Code Competition. There were only
three entries the first year, the judges couldn't figure out how one of them worked,
and the competition was cancelled.

:-)

Alan

Sweavo

unread,
Dec 7, 2001, 5:05:20 AM12/7/01
to
> #!/usr/bin/perl
> print map(@t[($_+$i++)%@ARGV]++=~/1/,@ARGV)?'n':'y';
>
> (53 chars)

Course if you dispense with the expensive GUI objects you get

exit map(@t[($_+$i++)%@ARGV]++=~/1/,@ARGV);

William Gilliland

unread,
Dec 7, 2001, 6:31:18 PM12/7/01
to
Sweavo <ps...@york.ac.uk> wrote:
:> #!/usr/bin/perl

: exit map(@t[($_+$i++)%@ARGV]++=~/1/,@ARGV);

You can get (very ugly) GUI and 3 less characters by ditching a pair
of parentheses and using die...

die map@t[($_+$i++)%@ARGV]++=~/1/,@ARGV;

Valid:
[ludwig:~] billg% ./sstest2.pl 4 4 1
Died at ./sstest2.pl line 2.

Not Valid:
[ludwig:~] billg% ./sstest2.pl 4 4 0 4 4 0 4 4 0
111 at ./sstest2.pl line 2.

That's down to 40 characters.

William Gilliland

unread,
Dec 7, 2001, 7:11:07 PM12/7/01
to
William Gilliland <bi...@runner.ucdavis.edu> wrote:

: die map@t[($_+$i++)%@ARGV]++=~/1/,@ARGV;

Down to 36 characters, and nicer output to boot:

map@t[($_+$i++)%@ARGV]++&&die,@ARGV;

Now it does nothing if the pattern is valid and dies if the pattern is
invalid.

--
This message brought to you by Bill Gilliland, bi...@ucdavis.edu

#! /usr/bin/perl
for(split q,,,q,x+GY[8>8Ox+I1L6*5*x+E1[V*X/x+C1K6*5+x\M1K8*8Jxx=^S&=UP=,.
q,x3B+&6&)3x=ZS(>'/=x1B3&6&)5x1^\,F5UP3xx,){if($i=6,/x/x){print"\n"}else{

Sweavo

unread,
Dec 10, 2001, 7:54:58 AM12/10/01
to
we're not worthy!

Mañungo

unread,
Dec 10, 2001, 9:38:43 AM12/10/01
to

With 67 characters, but allows multiplex (not sync):
map{s/\d/$t[$i]--;$t[($&+$i)%@ARGV]++/eg;$i++}@ARGV;map$_&&die,@t;

Example: ./ss.pl [654] [22] 2


Mañungo.


William Gilliland wrote:
>
> Down to 36 characters, and nicer output to boot:
>
> map@t[($_+$i++)%@ARGV]++&&die,@ARGV;
>
> Now it does nothing if the pattern is valid and dies if the pattern is
> invalid.
>
> --
> This message brought to you by Bill Gilliland, bi...@ucdavis.edu
>
> #! /usr/bin/perl
> for(split q,,,q,x+GY[8>8Ox+I1L6*5*x+E1[V*X/x+C1K6*5+x\M1K8*8Jxx=^S&=UP=,.
> q,x3B+&6&)3x=ZS(>'/=x1B3&6&)5x1^\,F5UP3xx,){if($i=6,/x/x){print"\n"}else{
> $x=-33+ord;while($i--){if(1<<$i<=$x){print'#';$x-=2**$i}else{print' '}}}}
>
>
>

----== posted via www.jugglingdb.com ==----

William Gilliland

unread,
Dec 12, 2001, 9:15:39 PM12/12/01
to
Sweavo <steveatjug...@hotmail.com> wrote:
: we're not worthy!

Nah, I didn't come up with the formula or the very cool use of map, I just
twiddled it down a little further in a few places.

Like here... one more character gone with some uglier output:

map@t[($_+$i++)%@ARGV]++&&&x,@ARGV;

Now it complains of a call of an undefined subroutine (&x) when the pattern's
not a valid siteswap. Uglier output, but it has three ampersands in a row
for bonus style points.

I don't know if this next one counts... it's pretty cheesy data hiding but
it is down another three characters to 32 (!):

map@t[($_+$i++)%$0]++&&&x,@ARGV;

To make this work, you need to rename the program file containing the
script to a number equal to the number of positions in the siteswap. Then
you need to run perl with the script instead of just running the script,
to avoid path problems, e.g.

% cp sstest3.pl 3
% perl 3 4 4 1
(Valid -- gives no result)
% perl 3 4 4 2
(Invalid -- gives undefined subroutine error)
% ./3 4 4 1
(Doesn't work -- $0 has ./3 instead of 3 like we need)

No, before you ask, I don't have a life.

Sweavo

unread,
Dec 13, 2001, 6:41:03 AM12/13/01
to
This is excellent! Not only the code but the method of invocation is
obfuscated too. In that case I humbly submit the following revised
documentation for its use

Prog runs <=> (script name = #balls in pattern) && run without pathname &&
Siteswap valid.
e.g. % cp sstest.pl 3; perl 3 4 4 1

"William Gilliland" <bi...@sandman.ucdavis.edu> wrote in message
news:9v930b$7o9$1...@woodrow.ucdavis.edu...

Rob Stone

unread,
Dec 13, 2001, 9:04:17 AM12/13/01
to
In article <9va47h$2qi$1...@pump1.york.ac.uk>, "Sweavo"
<steveatjug...@hotmail.com> wrote:

I think the documentation should be include in hte script in pod format !

-- Rob.

.........................................................................
Rob Stone, Psychology, University of York, York, YO10 5DD. 01904 433161
remove NOSPAM to mail me
.......................................................................

Nathan Hoover

unread,
Dec 13, 2001, 3:56:26 PM12/13/01
to
I don't usually go for this stuff, but I have to say that is beautiful. Not
only is it short (and has &&&), but it's even got an obfuscated command line
usage! Perfect.

---Nathan

"William Gilliland" <bi...@sandman.ucdavis.edu> wrote in message
news:9v930b$7o9$1...@woodrow.ucdavis.edu...

William Gilliland

unread,
Dec 13, 2001, 9:54:40 PM12/13/01
to
Nathan Hoover <nat...@movaris.com> wrote:
: I don't usually go for this stuff, but I have to say that is beautiful. Not

: only is it short (and has &&&), but it's even got an obfuscated command line
: usage! Perfect.

An even more obfuscated usage lets you shave off one more character, down
to 31... although I don't know if using a data file counts as cheating or
not. I suppose its the same number of keystrokes as entering it on the
command line.

for(<>){@t[($_+$i++)%$0]++&&&x}

For this to work, you not only need to name the script with the number
of entries in the siteswap, you need to have a file with the siteswap,
one number per line (and no newline at the end of the file). Then perl
the script as before.

e.g.:

% cp sstest4.pl 4
% cat valid-ss
5
5
5
1% perl 4 valid-ss
% cat invalid-ss
5
5
5
2% perl 4 invalid-ss
Undefined subroutine &main::x called at 4 line 32, <> line 4.

You can replace $0 with $. in this case if you want. Same number of
keystrokes, but the latter doesn't require renaming the script. Not
sure if that's a bug or a feature...

0 new messages