Как сгенерировать массив со случайными значениями, не используя цикл? - PullRequest
24 голосов
/ 04 ноября 2010

Как я могу создать массив в Perl с 100 случайными значениями, без использования цикла?

Я должен избегать всякого рода циклов, таких как «для», foreach », пока. Это мое упражнение из моей лаборатории. Я не могу найти способ решить эту проблему, потому что я новичок в Perl.

В C генерация этого массива будет очень простой, но я не знаю, как это сделать в Perl.

Ответы [ 24 ]

5 голосов
/ 04 ноября 2010

Использование анонимного подпрограммы и рекурсии:

use strict;
use warnings;

my @foo;
my $random;
($random = sub {
        push @{$_[0]}, rand;
        return if @{$_[0]} == $_[1];
        goto \&$random;
})->(\@foo, 100);

print "@foo\n";
print scalar @foo, "\n";

Использование вычисленного goto для всех поклонников фортрана:

use strict;
use warnings;

sub randoms {
        my $num = shift;
        my $foo;
        CARRYON:
                push @$foo, rand;
                # goto $#{$foo} < 99 ? 'CARRYON' : 'STOP';
                goto ( ('CARRYON') x 99, 'STOP' )[$#$foo];
        STOP:
                return @$foo;
}

my @foo = randoms(100);
print "@foo\n";
print scalar(@foo)."\n";

2 анонимных подпрограмм и ссылка на массив:

use strict;
use warnings;

my @bar = sub {  return &{$_[0]} }->
(
        sub {
                push @{$_[1]}, rand;
                goto \&{$_[0]}
                        unless scalar(@{$_[1]}) == $_[2];
                return @{$_[1]};
        },
        [],
        100
);

print "@bar\n";
print scalar(@bar), "\n";
5 голосов
/ 05 ноября 2010
#!/usr/bin/perl

use strict;
use warnings;

my $x = 99;
my @rands = (rand,(*x=sub{rand,(map{*x->($x,sub{*x})}($x)x!!--$x)})->($x,*x));

use feature 'say';
say for @rands;
4 голосов
/ 07 ноября 2010

Еще один глупый метод, как насчет использования связанного массива, который возвращает случайное значение?

use strict;
use warnings;

package Tie::RandArray;
use Tie::Array;
our @ISA = ('Tie::StdArray');
sub FETCH  { rand; }

package main;
my @rand;
my $object = tie @rand, 'Tie::RandArray';
$#rand=100;
my @a= @somearray;
warn "@a";

Конечно, связанный массив может кэшировать значения, так что второй массив не потребуется для стабильной работызначения.

4 голосов
/ 05 ноября 2010

Кто-то попросил чисто регулярное выражение.Как насчет

#!/usr/bin/perl
open my $slf, $0;
undef $/;
(my $s = <$slf>) =~ s/./rand()." "/eggs;
$s .= rand();
4 голосов
/ 04 ноября 2010
    push @array, rand;
    push @array, rand;
    # ... repeat 98 more times
4 голосов
/ 04 ноября 2010

Без циклов Perl:

#!/usr/bin/perl
use strict;
use warnings;

@ARGV=q!echo 'int rand(void); int printf(const char *format, ...); int main(void) { int i; for(i=0;i<100;++i)printf("%d\\\\n",rand()); return 0; }' | gcc -x c - && ./a.out |!;
chomp(my @array=<>);
3 голосов
/ 09 ноября 2010

это ужасно, но это работает. foreach просто показывает, что это так.

#!/usr/bin/perl

rand1();

$idx = 1;

foreach $item (@array) {
    print "$idx - $item\n";
    $idx++;
}

exit;



sub rand1() {
    rand2();
    rand2();
    rand2();
    rand2();
}

sub rand2() {
    rand3();
    rand3();
    rand3();
    rand3();
    rand3();
}

sub rand3() {
    push @array, rand;
    push @array, rand;
    push @array, rand;
    push @array, rand;
    push @array, rand;
}
3 голосов
/ 04 ноября 2010

Рекурсия:

sub fill_rand {
 my ($array, $count) = @_;
   if ($count >= 1) {
   unshift @$array, rand();
   fill_rand ($array, --$count);
 }
}

my @array;
fill_rand (\@array, 100);

Версия "Оптимизирован для хвоста":

sub fill_rand {
    my $array = shift;
    my $count = shift;
    unshift @$array, rand();
    if ($count > 1) {
       $count--;
       @_ = ($array, $count);
       goto &fill_rand;
    }
}

my @array;
fill_rand(\@array, 100);

Использование eval:

my @array;
eval("\@array = (" . ("rand(), " x 100) . ");");

Если вы предполагаете, что мой perl является случайным (не необоснованным предположением), вы можете использовать сам файл perl в качестве источника случайных данных:

open FILE, __FILE__ or die "Can't open " . __FILE__ . "\n";
my $string;
read FILE, $string, 100;
close FILE;
my @array = map { ord } split //, $string;

Конечно, вы каждый раз будете получать одни и те же результаты, но это полезно для тестирования.

2 голосов
/ 04 ноября 2010
@foo = (rand(), rand(), rand(), ... rand());
2 голосов
/ 04 ноября 2010
my $u;

open(URAND, "/dev/urandom") || die $!;

read(URAND, $u, 100);

close URAND;

my @array = split(/ */, $u);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...