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.
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; | [reply] [Watch: Dir/Any] [d/l] |
|
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!! | [reply] [Watch: Dir/Any] [d/l] [select] |
|
... 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
| [reply] [Watch: Dir/Any] [d/l] |
|
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
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++;
}
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|
|
|
|
|
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.
| [reply] [Watch: Dir/Any] [d/l] |
|
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} ... *
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Disclaimer: although the series operator is fairly new, it was introduced before TimToady read this question ;-)
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
|
|
|
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?"
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
|
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
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!
| [reply] [Watch: Dir/Any] [d/l] |
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}'
| [reply] [Watch: Dir/Any] [d/l] [select] |
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 );
}
| [reply] [Watch: Dir/Any] [d/l] |
Re: Generate the perl sequence 1, 11, 111, ....
by Skeeve (Parson) on Oct 10, 2008 at 08:39 UTC
|
perl -e 's/$/$\//;print while s/$/1/'
s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
+.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
perl -le'print while s/$/1/'
| [reply] [Watch: Dir/Any] [d/l] |
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++;
}
| [reply] [Watch: Dir/Any] [d/l] |
|
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...
| [reply] [Watch: Dir/Any] [d/l] [select] |
Numerically generate the perl sequence 1, 11, 111, ....
by Narveson (Chaplain) on Oct 12, 2008 at 09:22 UTC
|
use POSIX;
my $number = 1;
while ($number <= POSIX::ULONG_MAX) {
print "$number, ";
$number *= 10;
$number++;
}
print '...';
| [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] [d/l] |
|
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. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
|
|
|
|
|
|
|