After reflecting on perl -le "print $==()=<>", I feel that the keyword "print" detracts from the purity of the concept.

So, how could you do it without any alphanumeric characters at all?

Rules:
• The contents of the argument to -e must not match /\w/. Note that this includes underscores!
• command-line arguments to perl (e.g. the -le) don't count, and neither does the (arbitrary) file name argument.
• If you write it as a file rather than as a -e, the contents of that file must not match /\w/, and the name of that file must be irrelevant to the solution.

Challange:
A line counter program. Those that don't quite work right (e.g. requires the last line to end in a \n to count it) can be exhibited for interest's sake, but should be noted as a partial solution or special case solution, as the case may be.

This may or may not be combined with Golf, as you wish.

Replies are listed 'Best First'.
Re: !~ /\w/ challenge, anyone?
by BrowserUk (Patriarch) on Feb 05, 2003 at 17:14 UTC

    perl -ne}{$./'' file

    Update: Jeffa pointed out that for the above to work on *nix, you need to single quote the whole thing, which in turn means switching the single quotes to double quotes like this:

    perl -ne'}{die$./""' file

    A variation on thelenm's theme below

    On Win32:perl -pe"}{*{'['|']'}=*."

    On *nix: perl -pe'}{*{"["|"]"}=*.' file


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

      Very clever: it avoids both an explicit print or the $_ variable by generating an error instead, that happens to state the result within the message.

Re: !~ /\w/ challenge, anyone?
by thelenm (Vicar) on Feb 05, 2003 at 17:53 UTC
    perl -lpe "}{${'~'^'!'}=$." file

    Note: I get a problem running this under bash, because it interprets the ! incorrectly. But stick it in a file and it will run correctly. e.g.,

    #!/usr/bin/perl -lp }{${'~'^'!'}=$.
    Update: fixed a typo, and I forgot to put file on the command line. And here's a new version that actually runs on the command line:
    perl -lpe '}{${"#"^"|"}=$.' file

    -- Mike

    --
    just,my${.02}

      Very nice, the first post of a practical general way of avoiding $_ instead of griping about it! Not bad as an obfus technique either, especially if you do it with a different pair of chars each time.
Re: !~ /\w/ challenge, anyone?
by broquaint (Abbot) on Feb 05, 2003 at 16:49 UTC
    Alrighty
    perl -lpe '++($_=(()=<>))' < file
    update: ack just noticed the $_ :-/
    HTH

    _________
    broquaint

      Can you do it without the "_" character? I think finding ways to stick something in there implicitly will be one of the essential skills of this kind of challange.

      Is it necessary to redirect file to the script instead of letting <> read the argument?

      I see that the ++ compensates for the fact that one line was already read via -p. Cute.

      —John

        Is it necessary to redirect file to the script instead of letting <> read the argument?
        Yep, otherwise it'll just hang waiting on STDIN.

        Here's a solution that adheres to the rules but is awful sneaky

        shell> cat > obfuwc.pl #!/usr/bin/perl -lp -s ++(${$::{$-}}=()=<>) ^D shell> chmod +x obfuwc.pl shell> ./obfuwc.pl --=_ < file
        So the actual code passes the /\w/ but sneaks through the rules by passing in _. I can't say I'm proud ;)
        HTH

        _________
        broquaint

Re: !~ /\w/ challenge, anyone?
by Abigail-II (Bishop) on Feb 05, 2003 at 22:06 UTC
    Here's a totally different solution. It's unlikely to work on non-Linux platforms:
    ()=<>;$!=$=;($:,$,,$;,$")=$!=~/.(.)..(.)(.)..(.)/; $;++;$*++;$;++;$*++;$;++;`$:$,$;$" $. >&$*`;

    Abigail

      Patch for Windows, AIX, OSF, Solaris. Hopefully this doesn't give the game away ;)
      ()=<>;$!++;$!+=$!;($",$,,$:)=$!=~/.(.)...(..)....(.).+/; $;++;$*++;$;++;$*++;$;++;`$:$,$" $. >&$*`;

      blyman

      The question should be:

      What is the text of the error with the code 60 on a Linux platform that fits the pattern /.(e)..(c)(e)..(o)./?


      Examine what is said, not who speaks.

      The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

      Very cute. I like the use of the magic in $!. But what does noze do on a Linux platform?

        I've no idea what noze does on a Linux platform. ;-)

        Abigail

No ... but how about a !~ /[a-z0-9]/i challenge?
by jeffa (Bishop) on Feb 05, 2003 at 18:38 UTC
    perl -lpe'}{$_=$.' file
    I mean really, just because underscore is matched by \w is no reason to exclude it from this challenge. (And yes, i too missed that requirement.)

    Oh drat ... i just realized that mine is very similar to thelenm's and his just beat mine up ...

    Oh double drat ... i just realized that this isn't mine at all ... i sub-consciously lifted it from Abigail-II over at Re: How To Count Lines In File?. My apologies, Abigail-II (and i finally figured out why you used the globs :)).

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Your solution has a '_' in it, so unfortunately it matches /\w/ ...

      -- Mike

      --
      just,my${.02}

      Care to share the insight as to why he used the globs?
        Sure, but this is just a hunch ...

        The problem with one-liners (;)) is that Unix prefers the -e argument (the code) to be quoted with double quotes, while Win32 requires that is it be quoted with single quotes. Unix allows single quotes, but most (if not all) shells will try to interpolate the dollar signs. The following code should work on Win32, but not in UNIX:

        # bash and sh [jeffa@trinity perl]$ perl -ple "}{$_=$." foo.pl Can't modify constant item in scalar assignment ... # csh and tcsh [jeffa@trinity ~/perl]$ perl -ple "}{$_=$." foo.pl Illegal variable name. # ksh $ perl -ple "}{$_=$." foo.pl Bareword found where operator expected ...
        In all of these cases, single quotes instead of double quotes would alleviate these errors. But .. it's not necessarily the double quotes themselves that cause the trouble, it's the dollar signs. So ... use globs.
        perl -ple "}{*_=*." foo.pl
        Now, Abigail-II never confirmed nor denied this, so i'll treat that as a successfully executed Unix command. ;)

        Update:
        Of course (as jmcnamara pointed out to me via /msg), Abigail-II appears to never use Windows ... kinda throws a monkey wrench in the theory, but ... globs still get around that quoting problem.

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        
Re: !~ /\w/ challenge, anyone?
by jsprat (Curate) on Feb 05, 2003 at 20:28 UTC
    How about this?

    perl -pe}{$\=$.file

Re: !~ /\w/ challenge, anyone?
by Abigail-II (Bishop) on Feb 05, 2003 at 21:12 UTC
    command-line arguments to perl (e.g. the -le) don't count

    Blah. Your challenge is too easy. With that allowed, you can do anything, trivially.

    $ perl -Mstrict='}); ()=<>; print $.; ({' -le '""' /etc/passwd 23

    Abigail