Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

incremental string generator - perl

Name: Anonymous 2008-10-09 14:27

real    1m21.853s
user    1m21.070s
sys     0m0.165s


This is on a 1.8ghz c2d. Incremental string generator from charset (999999 passes). Can anyone think of a more efficient way?

my $alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !?";

my $pass = "a";

for (my $i = 0; $i < 1000000; $i++) {
  $pass = nextPass($pass, $alpha);
}

sub nextPass {
  my ($in, $alpha) = @_;
  my @pass = split //, $in;
  my @set = split //, $alpha;
  my $current = $#pass;
  my $done = 0;
  while (!$done) {
    # is the current character the end of the set?
    if ($pass[$current] eq $set[$#set]) {
      # set the current character to the start of the set
      $pass[$current] = $set[0];
      # is the current character the beginning of the pass?
      if ($current == 0) {
        # add the start of the set to the end of the pass and finish
        push(@pass, $set[0]);
        $done = 1;
      } else {
        $current--;
      }
    } else {
      my $spot = index($alpha, $pass[$current]) + 1;
      $pass[$current] = $set[$spot];
      $done = 1;
    }
  }
  my $out = join "", @pass;
  return $out;
}

Name: Anonymous 2008-10-10 2:32

OP, seriously, read SICP.

Original:
use Benchmark qw(:all);

my $alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !?";

my $pass = "a";

timethis (4, sub{
for (my $i = 0; $i < 10000; $i++) {
  $pass = nextPass($pass, $alpha);
}
});

sub nextPass {
  my ($in, $alpha) = @_;
  my @pass = split //, $in;
  my @set = split //, $alpha;
  my $current = $#pass;
  my $done = 0;
  while (!$done) {
    # is the current character the end of the set?
    if ($pass[$current] eq $set[$#set]) {
      # set the current character to the start of the set
      $pass[$current] = $set[0];
      # is the current character the beginning of the pass?
      if ($current == 0) {
        # add the start of the set to the end of the pass and finish
        push(@pass, $set[0]);
        $done = 1;
      } else {
        $current--;
      }
    } else {
      my $spot = index($alpha, $pass[$current]) + 1;
      $pass[$current] = $set[$spot];
      $done = 1;
    }
  }
  my $out = join "", @pass;
  return $out;
}


result: timethis 4:  6 wallclock secs ( 5.34 usr +  0.00 sys =  5.34 CPU) @  0.75/s (n=4)

Modified:
use strict;
use Benchmark qw(:all);

sub make_passer($){
    my @chars=split //,shift;
   
    my $last=$chars[$#chars];
    my %re=map{
        $chars[$_]    => defined $chars[$_+1]?$chars[$_+1]:$chars[0]
    } 0..$#chars;
   
    sub{
        my($line)=@_;
        for(1..length $line){
            for(substr $line,(length $line)-$_,1){
                $_=$chars[0],next if $_ eq $last;
               
                $_=$re{$_};
                return $line;
            }
        }
       
        "$chars[0]$line"
    }
}

my $sub=make_passer "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !?";
my $val="a";

timethis 4,sub{
    for(0..10000){
        $val=$sub->($val);
    }
}


result: timethis 4:  0 wallclock secs ( 0.25 usr +  0.00 sys =  0.25 CPU) @ 16.00/s (n=4)

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List