Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Generate the perl sequence 1, 11, 111, ....

by alih110 (Novice)
on Oct 10, 2008 at 07:03 UTC ( [id://716367]=perlquestion: print w/replies, xml ) Need Help??

alih110 has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I need to generate the following sequence in my perl program => 1, 11, 111, 1111, 11111, .... Anyone can help me what is the simplest way to generate this kind of sequnce? Is there some name for this kind of sequence? Thanks.

Replies are listed 'Best First'.
Re: Generate the perl sequence 1, 11, 111, ....
by moritz (Cardinal) on Oct 10, 2008 at 07:41 UTC
    my @ones = map { 1 x $_ } 1..100;
      I wanted to post something similar
      @ones =map("1" x $_, 0..10) ;
      What I don't understood is how it is possible that map can accept different syntax. For example, is it possible to write a perl subroutine that does the same thing, myPerlSub BLOCK LIST
      Thnx
      LuCa

      UPDATE: thnx for the explanation!!
        ... is it possible to write a perl subroutine that does the same thing, myPerlSub BLOCK LIST
        Absolutely. See perlsub and in particular Prototypes.
        >perl -wMstrict -le "sub mysub (&@) { my $coderef = shift; map $coderef->($_), @_; } my @out = mysub { $_ += 33 } 0 .. 5; print qq{@out}; " 33 34 35 36 37 38
        The odd-looking syntax
        mysubroutine {block} @list;
        is mentioned in perlsub. Look in the section on prototypes where it describes the "&" prototype character, particularly the sentence "An & requires an anonymous subroutine, which, if passed as the first argument, does not require the sub keyword or a subsequent comma" and also the examples "try", "catch", and "mygrep".
         
        On the other hand, it looks to me that map is somewhat more magical than the examples in perlsub; if you call
        map (sub { "1" x $_ }, (1..10));
        it returns an array of coderefs (references to subroutines) which is not at all what is needed here.
         
        Also, not all builtin functions have regular enough syntax to be expressed with a prototype at all. map is one of them:
        perl -wle 'print prototype("CORE::map")'
        prints
        Use of uninitialized value in print at -e line 1.
        What I don't understood is how it is possible that map can accept different syntax. For example, is it possible to write a perl subroutine that does the same thing, myPerlSub BLOCK LIST
        Thnx
        LuCa

        UPDATE: thnx for the explanation!!

        I personally believe that you shouldn't be too surprised. Quite a lot of builtin functions accept different kinds of arguments. Just see the first one that springs to mind, e.g. perldoc -f split:

        split /PATTERN/,EXPR,LIMIT split /PATTERN/,EXPR split /PATTERN/ split Splits the string EXPR into a list of strings and returns +that list. By default, empty leading fields are preserved, and +empty trailing ones are deleted. (If all fields are empty, they +are considered to be trailing.)

        Ok, the case of map is somewhat more surprising: actually, not only is it possible, as others explained to you, to implement the syntax above with Prototypes (which indeed are there much to the objective of letting you write subs that behave like builtins) but it is currently impossible to implement the alternate syntax of map() i.e. namely that with an expression since that would be more akin to to a macro, but there's not provision for such a beast under Perl 5. Of course you can write a sub that accepts a generic argument as the first one and when you use it, then the argument can be an expression, but that would be evaluated and passed to the sub as a scalar, not as an expression to be evaluated by your sub itself.

        HTH.

        --
        If you can't understand the incipit, then please check the IPB Campaign.

      Is there some name for this kind of sequence

      1 liner :-)

        Hello all, This is my very first post/reply to perlmonks.org :)
        my $one_literal = "1"; my $counter = 1; while ( 1 ) { for ( my $i = 1; $i <= $counter; $i++ ) { printf "$one_literal"; } printf "\n"; $counter++; }
Re: Generate the perl sequence 1, 11, 111, ....
by Fletch (Bishop) on Oct 10, 2008 at 13:14 UTC
    ones = "1" : [ x ++ "1" | x <- ones ]

    That and Language::Haskell should get you all the 1s you need . . .

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      Tsk, tsk, Haskell is such a verbose language. :) In Perl 6 it' just:
      [\~] 1 xx *
      where that just says "make an arbitrarily long list of 1's and reduce them using concatenation (the ~ operator), returning partial results in a list". That even works today in pugs if you replace the * with, say, 10:
      pugs> .say for [\~] 1 xx 10 1 11 111 1111 11111 111111 1111111 11111111 111111111 1111111111
      Or using the new, spiffily readable ... infix, it's even shorter:
      1...{$_~1}
      That just extends the list on the left by concatenating a 1 onto the previous last value of the list. But nobody has implemented that one yet, since we only invented it on Sunday... :)

      The cool thing about it is that (if you're not golfing it) you can write however much of the list you like as an example for the human reader, and give the parameter a better name:

      1,11,111,1111 ... {$^previous ~ 1}

      Update: nowadays (2010/04/03) the closure goes on the left, so we'd write those more like:

      1,*~1...* 1, 11, 111, 1111, {$^previous ~ 1} ... *
        Disclaimer: although the series operator is fairly new, it was introduced before TimToady read this question ;-)
        where that just says "make an arbitrarily long list of 1's and reduce them using concatenation (the ~ operator), returning partial results in a list".

        I personally believe that I need some clarifications: I understand clearly that the backslash implements the "returning partial results" thingie, but I am not sure about is semantics. In particular, is it a metaoperator modifying any binary operator, and if so, how? Or is really [\ ] a distinct metaoperator wrt [ ], with the former being the "reduction returning partial results" and the latter simply "reduction?"

        --
        If you can't understand the incipit, then please check the IPB Campaign.

        I have one more consideration, and a pair of questions, which I forgot to mention when I wrote my previous followup:

        1. I don't know if it's the same reason why that particular symbol was chosen, but I find the appearance of [\ ] to be extremely representative of the "take partial results" thingie since it looks much like a triangle which is maximally evident here, given that the output "is also a triangle" but has more general sense with common reduction situations one may naturally feel psychologically at ease with, charachterized by "results that grow." (Sorry for the sloppy parliance, which I believe to be appropriate here, though.)
        2. I also wonder if the same behaviour can be obtained by means of a suitable adverb (i.e. whether one such adverb is provided!) acting on [ ]... well if adverbs do apply to meta-operators at all, that is, which I ignore altogher;
        3. last and perhaps most importantly, given that [\ ] returns the list of partial reductions, shouldn't it for completeness also include the 0-th one? Namely, the neutral element for the bynary operation passed to it, if any. (I already can feel that the "if any" bit could prompt for a negative answer, yet I feel that a positive one would be mathematically more appropriate.)
        --
        If you can't understand the incipit, then please check the IPB Campaign.
Re: Generate the perl sequence 1, 11, 111, ....
by Random_Walk (Prior) on Oct 10, 2008 at 11:36 UTC

    As this infinite series could get rather large you may like to create an iterator to return the next member from the series each time it is called

    #!/usr/bin/perl use strict; use warnings; # make our iterator (a subroutine which holds its own state) my $ones = seq_gen(1); while (1) { # call iterator and print result my $next = $ones->(); print "$next\n"; sleep 1; } sub seq_gen { # generate and return a subroutine that captures its entry values +and # gives you the next member each time it is called my $seq = shift; my $string = ''; return sub { $string .= $seq; return $string; } }

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!
Re: Generate the perl sequence 1, 11, 111, ....
by JavaFan (Canon) on Oct 10, 2008 at 19:48 UTC
    Such a home work assignment should immediately trigger the term 'recursion'. The best way to impress your teacher is:
    perl -E'sub _{push@_,say@_;&_}_'
    It even starts with 0 1's, for extra credits.

    If you want to golf, you might want to try

    perl -E'{$_.=say;redo}'
Re: Generate the perl sequence 1, 11, 111, ....
by monarch (Priest) on Oct 10, 2008 at 07:17 UTC
    my $one = "1"; my @ones = ( $one ); while ( 1 ) { $one .= "1"; push( @ones, $one ); }
Re: Generate the perl sequence 1, 11, 111, ....
by Skeeve (Parson) on Oct 10, 2008 at 08:39 UTC

    For the fun of it:

    perl -e 's/$/$\//;print while s/$/1/'

    s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
    +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e

      Or more simply:

      perl -le'print while s/$/1/'
Re: Generate the perl sequence 1, 11, 111, ....
by johndageek (Hermit) on Oct 10, 2008 at 15:38 UTC
    just another simple minded shot:
    $a=1; while ($b< 100){ $a =~ s/1$/11/; print "$a\n"; $b++; }

    Enjoy!
    Dageek

      I personally believe that

      • a "better" s-based solution was already posted by jwkrahn, in particular:
      • there's no need to match a 1 at the end of the string, and avoiding to do so could generalize the code to spit out the sequence to begin with zero 1's - not that anybody requested it, but it's such a tiny violation of YAGNI for both a simpler syntax and added flexibility that I would only avoid it if it were expressedly ruled out;
      • we recommend not to use $a and $b as general purpose variables all the time, which would be especially important here, given that the OP is clearly a newbie;
      • this thread is clearly facetious in many ways, but as a general programming rule, it's awkward and error prone that you somehow unnecessarily duplicate information, holding it in two variables where one would suffice: namely in $a as the length of $a itself and in $b as an integer, whereas the two quantities are fundamentally the same. Once you use only one variable, perhaps taking advantage of $_ to use smart defaults, and switching to the while statement modifier, your code could be morphed into:
      perl -le 's/$/1/, print while 100 > length'

      Incidentally, now that I notice, the anchor is not necessary at all. If it were not for a mandatory /e modifier, this could make for a golfed solution just as good as JavaFan's

      perl -E'{s//say/e,redo}'

      but that's not the case...

      --
      If you can't understand the incipit, then please check the IPB Campaign.
Numerically generate the perl sequence 1, 11, 111, ....
by Narveson (Chaplain) on Oct 12, 2008 at 09:22 UTC

    What if

    1, 11, 111, 1111, 11111, ....

    is meant to be a sequence of numbers?

    use POSIX; my $number = 1; while ($number <= POSIX::ULONG_MAX) { print "$number, "; $number *= 10; $number++; } print '...';
      What if 1, 11, 111, 1111, 11111, .... is meant to be a sequence of numbers?

      Then there's nothing wrong with generating them as strings, because perl will automatically convert between these two as needed.

        Well, but the conversion costs something. So in Perl 6, if you're worried about efficiency, you'd probably write it like this:
        1,11,111,1111 ... { $^prev * 10 + 1 }
        Unless we can make the "whatever" version intuit such an algebraic relationship, in which case it would just be:
        1,11,111,111 ... *
        Just how far we could/should drive the intuition of the series operator is an interesting question.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://716367]
Approved by GrandFather
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (2)
As of 2024-03-19 04:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found